Jak usunąć linię, jeśli jest dłuższa niż XY?


21

Jak mogę usunąć wiersz, jeśli jest on dłuższy niż np .: 2048 znaków?


Czy nalegasz na używanie sed? Jest to łatwe, na przykład w Pythonie. I bez wątpienia jeszcze łatwiejsze w perlu. Chociaż pytanie nie jest zbyt dobrze zdefiniowane. Skopiować plik, usuwając wszystkie wiersze dłuższe niż 2048, czy coś innego?
Faheem Mitha

Odpowiedzi:


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

3
Pojawia się komunikat o błędzie sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi prawdopodobnie chcesz zainstalować wersję GNU zamiast wersji BSD dostarczanej z komputerem Mac. To jest łatwe dzięki
naparowi

Pytanie brzmi „jeśli dłuższy niż XY (np. 2048 znaków)”. Zatem musi to być> 2048, a nie => 2048
ajcg

1
@ajcg, jest> 2048. Zwróć uwagę, że na końcu wyrażenia występuje dodatkowy okres na dopasowanie do 2049. postaci.
forcefsck

@forcefsck i nie byłoby lepiej, gdybyś zabrał go „^”? (za pomocą polecenia usuwasz tylko wiersze, które „zaczynają się od XYZ”, ale jeśli XYZ jest w innej części wiersza, to go nie usuwa)
ajcg

7

Oto rozwiązanie, które usuwa wiersze zawierające 2049 lub więcej znaków:

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

Wyrażenie /.{2049}/dbędzie pasować do dowolnego wiersza zawierającego co najmniej 2049 znaków i usuwa je z wejścia, tworząc tylko krótszy wiersz na wyjściu.

Z awkdrukowaniem linii o długości 2048 lub krótszej:

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

Naśladując sedrozwiązanie dosłownie za pomocą awk:

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

1
Pojawia się komunikat o błędzie sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi Teraz zaktualizowane i przetestowane na macOS Mojave.
Kusalananda

2

Coś takiego powinno działać w Pythonie.

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

1
Osobiście, @Faheem, wolę twoją odpowiedź. Powodem jest to, że bardzo łatwo mi było zmienić to na „usuń wszystkie linie mniejsze niż x”. Nie używam Pythona przez cały czas, ale kiedy to robię, zawsze czuję, że powinienem się tego dobrze nauczyć.
ixtmixilix

@ixtmixilix: Tak, używanie w pełni funkcjonalnego języka, takiego jak Python, jest dość elastyczne. Dziękuję za komentarz.
Faheem Mitha

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

+1 Nie -ljest to jednak potrzebne.
Joseph R.

Nie działa dla mnie. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
wedi

Możesz spróbować length($_) > 2048 && print. lengthw length($_)każdym razie jest skrótem .
MaratC,

0

Powyższe odpowiedzi nie działają w systemie Mac OS X 10.9.5.

Działa następujący kod:

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

Chociaż nie pytano, ale podano w celach informacyjnych, można uzyskać następujący kod:

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


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

Ach Zainstalowałem wersję GNU zamiast wersji BSD dostarczanej z komputerem Mac, jak sugerowano powyżej @ Freedom_Ben. Ale Kusalananda znalazł przełącznik, aby włączyć rozszerzone wyrażenia regularne. Więc powinieneś pójść z jego rozwiązaniem, jeśli nadal masz ten problem. ;)
śr.

0

W przypadku gnu-sed możesz użyć flagi -r, aby uniknąć wpisywania odwrotnych ukośników i przecinka, aby zdefiniować otwarty interwał:

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

z:

  • x {2049} oznacza dokładnie 2049 xs
  • x {2049,3072}, co oznacza od 2049 do 3072 xs
  • x {2049,} co najmniej 2049 xs
  • x {, 2049} co najwyżej 2049 xs

Aby interwały nie pasowały do ​​większych wzorów, potrzebne byłyby kotwice linii, takie jak

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.