Come eliminare la linea se più lunga di XY?


21

Come posso eliminare una linea se è più lunga di es: 2048 caratteri?


Insisti nell'usare sed? Questo è facile, ad esempio in Python. E senza dubbio ancora più facile in perl. Sebbene la domanda non sia terribilmente ben definita. Copia un file, rimuovendo tutte le righe più lunghe del 2048 o qualcos'altro?
Faheem Mitha,

Risposte:


22
sed '/^.\{2048\}./d' input.txt > output.txt

3
Ricevo il messaggio di errore sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
wedi,

1
@wedi probabilmente vorrai installare la versione GNU invece della versione BSD fornita con Mac. Questo è facile con brew
Freedom_Ben

La domanda dice "se più lungo di XY (ad es. 2048 caratteri)". Quindi deve essere> 2048 e non => 2048
ajcg

1
@ajcg, è> 2048. Nota che alla fine del regex c'è un periodo in più per abbinare il 2049 ° personaggio.
forcefsck

@forcefsck e non sarebbe meglio se lo porti via "^"? (con il tuo comando stai rimuovendo solo le righe che "iniziano con XYZ", ma se XYZ si trova in un'altra parte della linea, non la cancellerà)
ajcg

7

Ecco una soluzione che elimina le righe che hanno 2049 o più caratteri:

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

L'espressione /.{2049}/dcorrisponderà a qualsiasi riga che contiene almeno 2049 caratteri e li cancella dall'input, producendo solo una riga più corta sull'output.

Con awklinee di stampa di lunghezza 2048 o inferiore:

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

Imitando la sedsoluzione letteralmente con awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out

1
Ricevo il messaggio di errore sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
wedi,

1
@wedi Ora aggiornato e testato su macOS Mojave.
Kusalananda

2

Qualcosa del genere dovrebbe funzionare in Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()

1
Personalmente, @Faheem, preferisco la tua risposta. Il motivo è che è stato molto facile per me trasformarlo in "elimina tutte le righe più piccole di x". Non uso Python sempre, ma quando lo faccio sento sempre che dovrei impararlo bene.
ixtmixilix,

@ixtmixilix: Sì, l'utilizzo di un linguaggio completo come Python è piuttosto flessibile. Grazie per il commento.
Faheem Mitha,

2
perl -lne "length < 2048 && print" infile > outfile

+1 Tuttavia -lnon è necessario.
Joseph R.

Non funziona per me. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
wedi,

Puoi provare length($_) > 2048 && print. lengthè una scorciatoia per length($_)comunque.
MaratC

0

Le risposte di cui sopra non funzionano per me su Mac OS X 10.9.5.

Il seguente codice funziona:

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

Sebbene non sia richiesto, ma fornito come riferimento, è possibile ottenere il seguente codice al contrario:

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


lol, but sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
alex gray

Ah. Ho installato la versione GNU invece della versione BSD fornita con Mac come suggerito da @Freedom_Ben sopra. Ma Kusalananda ha trovato il passaggio per abilitare la regex estesa. Quindi dovresti andare con la sua soluzione se hai ancora quel problema. ;)
wedi,

0

Con gnu-sed, puoi usare il flag -r, per evitare di digitare le barre rovesciate e una virgola, per definire un intervallo aperto:

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

con:

  • x {2049} che significa esattamente 2049 xs
  • x {2049,3072} che significa dal 2049 al 3072 xs
  • x {2049,} che significa almeno 2049 xs
  • x {, 2049} che significa al massimo 2049 xs

Per gli intervalli, per non corrispondere a schemi più grandi, avresti bisogno di ancore di linea come

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.