Jak usunąć linie krótsze niż XY?

29

Znalazłem pytanie, jak usunąć linie dłuższe niż 2048 znaków:

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

P: Ale jak mogę usunąć linie krótsze niż 4 znaki? Więc usuń wiersze o długości 1, 2 lub 3 w pliku.

AKTUALIZACJA: Dzięki za wiele DOBRYCH odpowiedzi, ale mogę zaznaczyć tylko jedną jako OK

evachrystyna
źródło

Odpowiedzi:

42

Możesz użyć sed. Poniższe spowoduje usunięcie wierszy o długości 3 znaków lub mniejszych:

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

Aby zapisać zmiany w pliku w miejscu, podaj -iopcję.

Jeśli twoja wersja sednie obsługuje rozszerzonej składni RE, możesz napisać to samo w BRE:

sed '/^.\{,3\}$/d' filename

który działałby ze wszystkimi sedwariantami.


Możesz także użyć awk:

awk 'length($0)>3' filename

Używanie perl:

perl -lne 'length()>3 && print' filename
diabelnie
źródło
sed '/^.\{,3\}$/d'nie działa z BSD sed: sed: 1: "/^.\{,3\}$/d": RE error: invalid repetition count(s). Wersja sed -r jest poprawna pod względem składniowym, ale nie usuwa wierszy.
Dereckson,
5

Kilka innych odmian:

grep .... file

lub

sed '/..../!d' file

lub

sed -n 's/./&/4p' file

lub

awk 'gsub(/./,"&")>3' file

lub

awk 'length>3' file

lub GNU awk:

awk 'NF>3' FS= file
Skrutator
źródło
1
Och, ten grep .... jest taki elegancki!
grofte
3

Oto rozwiązanie Vima z użyciem trybu Ex Vima i globalpolecenia.

Jest to bardzo podobne do używania sed, tyle że niektóre specjalne znaki („{”, „}”) muszą zostać usunięte.

:g/^.\{,3\}$/d

Używając trybu Very Magic Regex Vima (\ v), można uniknąć tego ucieczki.

:g/\v^.{,3}$/d

Zobacz także: pomoc magii

Use of "\v" means that in the pattern after it all ASCII characters except
'0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.  "very magic"

Czasami przydatne jest również odwrotne działanie vglobal.

:v/\v^.{,3}$/d

usunie wszystko oprócz wierszy do 3 znaków.

Gergap
źródło
1

aby bezpośrednio usunąć linie, możesz:

sed -ri '/.{4}/!d' /path/to/file

Lub BRE:

sed -i '/.\{4\}/!d' /path/to/file

Jeśli wiersz nie zawiera 4 lub więcej znaków, jest usuwany.

f=/path/to/file
cat <<GREP >"$f"
    $(grep -E ".{4}" "$f")
GREP

Wykonanie powyższego w podpowłoce zastępowania poleceń zapewni, że grepdostanie na nim deskryptor odczytu, zanim kot zacznie do niego pisać, ale <<HEREDOCzapewni również, że wynik pozostanie przesyłany strumieniowo i nie spowoduje błędów długości argumentów.

mikeserv
źródło
0
sed '/^.\?.\?.\?$/d' input.txt > output.txt
Hauke ​​Laging
źródło
0

Możesz użyć grep:

Jeśli policzysz początkowe spacje w długości linii:

grep -e '[^\ ]\{4,\}' file

Jeśli nie policzysz początkowych spacji w linii na linii:

grep -e '[^\]\{4,\}' file
Cuonglm
źródło