Como deletar todas as linhas em um arquivo de texto que tenha menos de ‘x’ caracteres?

Como deletar todas as linhas em um arquivo de texto que tenha menos de ‘x’ caracteres?

Como posso excluir todas as linhas em um arquivo de texto que tenha menos de 'x' letras OU números OU símbolos? Não posso usar awk 'length($0)>'porque incluirá espaços.

Responder1

Supondo que você queira excluir linhas que contenham menos nsímbolos gráficos:

awk -v n=5 '{ line = $0; gsub("[^[:graph:]]", "") } length >= n { print line }'

Isso exclui todos os caracteres que não correspondem [[:graph:]]. Se o comprimento da string restante for maior ou igual a n, a linha (não modificada) será impressa.

O valor de né fornecido na linha de comando.

[[:graph:]]é equivalente a [[:alnum:][:punct:]], que por sua vez é igual a [[:alpha:][:digit:][:punct:]]. É aproximadamente o mesmo, [[:print:]]mas não corresponde a espaços.

Em vez de [^[:graph:]], você poderia usar [[:blank:]]para excluir todas as tabulações ou espaços.

Com sed, seguindo o código acima awkquase literalmente,

sed -e 'h; s/[^[:graph:]]//g' \
    -e '/.\{5\}/!d; g'

ou, simplificado (contando apenas caracteres que não sejam espaços em branco),

sed -e 'h; s/[[:blank:]]//g' \
    -e '/...../!d; g'

Isso primeiro salva a linha atual no espaço de espera com h. Em seguida, ele exclui todos os caracteres não gráficos (ou caracteres em branco na segunda variação) na linha com s///g. Se a linha contiver menos de 5 caracteres (altere para qualquer número desejado ou altere o número de pontos na segunda variação), a linha será excluída. Caso contrário, a linha armazenada é buscada no espaço de espera ge (implicitamente) impressa.

Responder2

sed -e 's/[^[:space:][:cntrl:]]/&/20' -e t -e d < file

imprimiria as linhas fileque contêm pelo menos 20 caracteres sem espaço em branco e sem controle (veja também [[:graph:]]ou [[:alnum:][:punct:]], não está claro quais caracteres você deseja incluir/excluir de sua descrição; tenha cuidado, pois em alguns sistemas, o caractere de espaço sem quebra está incluído graphe não em space).

A ideia é que ele tente substituir a 20ª ocorrência de um caractere que não seja espaço em branco/controle por ele mesmo ( &) e ramificamos se essa substituição for bem-sucedida ( t), ignorando assim a dação (excluir).

Com awkvocê poderia fazer:

awk 'gsub(/[^[:space:][:cntrl:]]/, "&") >= 20' < file

Baseando-se no fato de que gsub()retorna o número de substituições que fez.

Com grep:

grep -E '^([[:space:][:cntrl:]]*[^[:space:][:cntrl:]]){20}' <  file

( (.*[^[:space:][:cntrl:]]){20}também funcionaria, mas seria mais caro).

Responder3

Isso excluirá as linhas que possuem 10 e menos de 10 caracteres:

sed -E '/^.{1,11}$/d' filename

OU

sed -r '/^.{1,11}$/d' filename  

Se você quiser cortar espaços, você pode usar:

sed -E 's/^[[:space:]]*//g;s/[[:space:]]*$//g;/^.{1,11}$/d' filename

Se você quiser fazer a exclusão no local (diretamente dentro do arquivo), use-euopção com ele.

Responder4

Usando Raku (née Perl6)

raku -ne '.put if chars( S:g/\s// ) >= 10;'  filename

ou

raku -ne '.put unless chars( S:g/\s// ) < 10;'  filename

ou

raku -ne '.put unless chars( S:g/\W// ) < 10;'  filename

ou

raku -ne '.put unless chars( S:g/<ws>// ) < 10;'  filename

Resumidamente, em Raku/Perl6 o operador "S maiúsculo" S///é usado para gerar uma string resultante desprovida de caracteres indesejados (por exemplo, espaços em branco), os caracteres da string resultante são contados com a charsfunção, comparados com "n" (usando 10 como exemplo) e finalmente - se o booleano for satisfeito - .putretornará a linha original intacta.

Nota 1: "S/// usa a mesma semântica que o operador s///, exceto que deixa a string original intacta e retorna a string resultante em vez de $/ ($/ ainda sendo definido com os mesmos valores de s///) ."

https://docs.raku.org/linguagem/regexes#S///_non-destructive_substitution

Nota 2: Em Raku/Perl6, modificadores de regex como :g(para 'global') são conhecidos como advérbios e são (geralmente) colocados no início do operador S///or s///, logo após o Sor s.

Nota 3: O .ponto em Raku/Perl6 é usado para chamar um método na variável de tópico $_, portanto a primeira 'palavra' do código .puté essencialmente uma abreviação de $_.put.

https://docs.raku.org/linguagem/5to6-nutshell#-%3E_Method_calls

Nota 4: Raku/Perl6 possui um conjunto muito mais restrito de sinalizadores de linha de comando. O -esinalizador ("executar") executa o código Raku/Perl6 na linha de comando. O -nsinalizador executa o código Raku/Perl6 em linha, ou seja, em cada linha de um arquivo de entrada, uma linha por vez, retornando um resultado. As duas bandeiras podem ser combinadas em uma -nebandeira, mas independentemente disso, a -ebandeira deve vir por último.

Links Perl_6:
https://docs.raku.org/linguagem/5to6-nutshell#Command-line_flags
https://github.com/rakudo/rakudo/wiki/Running-rakudo-from-the-command-line

informação relacionada