Wie lösche ich eine Zeile, die länger als XY ist?

21

Wie kann ich eine Zeile löschen, die länger als zB 2048 Zeichen ist?

LanceBaynes
quelle
Bestehen Sie darauf, sed zu verwenden? Dies ist zum Beispiel in Python einfach. Und ohne Zweifel noch einfacher in Perl. Obwohl die Frage nicht sehr genau definiert ist. Eine Datei kopieren, alle Zeilen entfernen, die länger als 2048 sind, oder etwas anderes?
Faheem Mitha

Antworten:

22
sed '/^.\{2048\}./d' input.txt > output.txt
forcefsck
quelle
3
Ich erhalte die Fehlermeldung sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
Mittwoch,
1
@wedi Sie möchten wahrscheinlich die GNU-Version anstelle der mit dem Mac gelieferten BSD-Version installieren. Dies ist einfach mit Brauen
Freedom_Ben
Die Frage lautet "wenn länger als XY (zB 2048 Zeichen)". Dann muss es> 2048 und nicht => 2048 sein
28.
1
@ajcg, Es ist> 2048. Beachten Sie, dass am Ende des regulären Ausdrucks ein zusätzlicher Punkt steht, der dem 2049. Zeichen entspricht.
Forcefsck
@forcefsck und es wäre nicht besser, wenn Sie es wegnehmen "^"? (Mit Ihrem Befehl entfernen Sie nur Zeilen, die "mit XYZ beginnen", aber wenn sich XYZ in einem anderen Teil der Zeile befindet, wird sie nicht gelöscht.)
30.
7

Hier ist eine Lösung, die Zeilen mit 2049 oder mehr Zeichen löscht:

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

Der Ausdruck /.{2049}/dstimmt mit jeder Zeile überein, die mindestens 2049 Zeichen enthält, und löscht diese aus der Eingabe. Dadurch wird in der Ausgabe nur eine kürzere Zeile erzeugt.

Mit awkDruckzeilen der Länge 2048 oder kürzer:

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

Die sedLösung wörtlich nachahmen mit awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out
Kusalananda
quelle
1
Ich erhalte die Fehlermeldung sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
Mittwoch,
1
@wedi Jetzt aktualisiert und auf macOS Mojave getestet.
Kusalananda
2

So etwas sollte in Python funktionieren.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()
Faheem Mitha
quelle
1
Persönlich, @Faheem, bevorzuge ich Ihre Antwort. Der Grund dafür ist, dass es mir sehr leicht gefallen ist, es in "Alle Zeilen löschen, die kleiner als x sind" umzuwandeln. Ich benutze Python nicht die ganze Zeit, aber wenn ich es tue, sollte ich es immer gut lernen.
ixtmixilix
@ixtmixilix: Ja, die Verwendung einer voll funktionsfähigen Sprache wie Python ist ziemlich flexibel. Danke für den Kommentar.
Faheem Mitha
2
perl -lne "length < 2048 && print" infile > outfile
MaratC
quelle
+1 Das -lwird aber nicht benötigt.
Joseph R.
Funktioniert bei mir nicht. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
Mittwoch,
Du kannst es versuchen length($_) > 2048 && print. lengthist eine Abkürzung für length($_)sowieso.
MaratC
0

Die obigen Antworten funktionieren unter Mac OS X 10.9.5 nicht.

Der folgende Code funktioniert:

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

Obwohl nicht gefragt, aber als Referenz zur Verfügung gestellt, kann die Umkehrung der folgenden Code erreicht werden:

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

wedi
quelle
lol, aber sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
alex grau
Ah. Ich habe die GNU-Version anstelle der BSD-Version installiert, die mit dem oben vorgeschlagenen Mac @Freedom_Ben geliefert wird. Aber Kusalananda fand den Schalter, um eine erweiterte Regex zu ermöglichen. Also sollten Sie mit seiner Lösung gehen, wenn Sie das Problem immer noch haben. ;)
Mittwoch,
0

Mit gnu-sed können Sie das Flag -r verwenden, um die Eingabe von Backslashes zu vermeiden, und ein Komma, um ein offenes Intervall zu definieren:

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

mit:

  • x {2049} bedeutet genau 2049 xs
  • x {2049,3072} bedeutet von 2049 bis 3072 xs
  • x {2049,} bedeutet mindestens 2049 xs
  • x {, 2049} bedeutet höchstens 2049 xs

Damit die Intervalle nicht mit größeren Mustern übereinstimmen, benötigen Sie Linienanker wie

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Benutzer unbekannt
quelle