Como excluir uma linha se for maior que XY?

21

Como posso excluir uma linha se ela for maior que por exemplo: caracteres 2048?

LanceBaynes
fonte
Você insiste em usar o sed? Isso é fácil, por exemplo, em python. E sem dúvida ainda mais fácil em perl. Embora a questão não esteja muito bem definida. Copiar um arquivo, removendo todas as linhas com mais de 2048 ou outra coisa?
Faheem Mitha 23/03

Respostas:

22
sed '/^.\{2048\}./d' input.txt > output.txt
forcefsck
fonte
3
Recebo a mensagem de erro sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
wedi 13/10
1
@ wedi você provavelmente deseja instalar a versão GNU em vez da versão BSD que acompanha o Mac. Isso é fácil com o brew
Freedom_Ben
A pergunta diz "se for maior que XY (por exemplo, 2048 caracteres)". Então deve ser> 2048 e não => 2048
ajcg 28/08
1
@ajcg, é> 2048. Observe que há um período extra no final da regex para corresponder ao 2049 ° caractere.
forcefsck
@forcefsck e não seria melhor se você tirar "^"? (com o seu comando, você está apenas removendo as linhas que "começam com XYZ", mas se o XYZ estiver em outra parte da linha, ele não será excluído)
ajcg
7

Aqui está uma solução que exclui linhas com 2049 ou mais caracteres:

sed -E '/.{2049}/d' <file.in >file.out

A expressão /.{2049}/dcorresponderá a qualquer linha que contenha pelo menos 2049 caracteres e os excluirá da entrada, produzindo apenas uma linha mais curta na saída.

Com awklinhas de impressão de comprimento 2048 ou menor:

awk 'length <= 2048' <file.in >file.out

Imitando a sedsolução literalmente com awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out
Kusalananda
fonte
1
Recebo a mensagem de erro sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
wedi 13/10
1
@wedi Agora atualizado e testado no macOS Mojave.
Kusalananda
2

Algo assim deve funcionar em Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()
Faheem Mitha
fonte
1
Pessoalmente, @Faheem, prefiro sua resposta. O motivo é que foi muito fácil transformá-lo em 'excluir todas as linhas menores que x'. Eu não uso Python o tempo todo, mas quando eu sempre sinto que devo aprender bem.
Ixtmixilix
@ixtmixilix: Sim, o uso de uma linguagem completa como o Python é bastante flexível. Obrigado pelo comentário.
Faheem Mitha
2
perl -lne "length < 2048 && print" infile > outfile
MaratC
fonte
+1 O -lnão é necessário, no entanto.
Joseph R.
Nao funciona para mim. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
wedi
Você pode tentar length($_) > 2048 && print. lengthé um atalho para length($_)qualquer maneira.
MaratC
0

As respostas acima não funcionam para mim no Mac OS X 10.9.5.

O código a seguir funciona:

sed '/.\{2048\}/d'.

Embora não seja solicitado, mas fornecido como referência, o inverso pode ser alcançado com o seguinte código:

sed '/.\{2048\}/!d'.

wedi
fonte
lol, mas sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
Alex Gray
Ah Eu instalei a versão GNU em vez da versão BSD que acompanha o Mac, como @Freedom_Ben sugerido acima. Mas Kusalananda encontrou a opção para ativar o regex estendido. Então você deve ir com a solução dele se ainda tiver esse problema. ;)
quarta
0

Com o gnu-sed, você pode usar o sinalizador -r, para evitar digitar as barras invertidas e uma vírgula, para definir um intervalo aberto:

sed -r  "/.{2049,}/d" input.txt > output.txt

com:

  • x {2049}, significando exatamente 2049 xs
  • x {2049,3072}, que significa de 2049 a 3072 xs
  • x {2049,} significando pelo menos 2049 xs
  • x {, 2049}, significando no máximo 2049 xs

Para os intervalos, para não corresponder a padrões maiores, você precisaria de âncoras de linha como

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Usuário desconhecido
fonte