Jak grep
tabulować (\ t) w plikach na platformie Unix?
Jak grep
tabulować (\ t) w plikach na platformie Unix?
Odpowiedzi:
Jeśli używasz GNU grep, możesz użyć wyrażenia regularnego w stylu Perla:
grep -P '\t' *
-P
opcji.
Sztuką jest użycie znaku $ przed pojedynczymi cudzysłowami. Działa również do cięcia i innych narzędzi.
grep $'\t' sample.txt
zsh
ile mi wiadomo, to również działa . Czy mógłbyś skomentować, co to jest semantyka tego $
znaku?
$'\t'' '
. Prawdziwy przykład, który pokazuje, że działa również z sh (nie tylko bash, który domyślnie nie jest zainstalowany na Androidzie) to busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
.
Nigdy nie udało mi się sprawić, aby metaznak „\ t” działał z grep. Znalazłem jednak dwa alternatywne rozwiązania:
<Ctrl-V> <TAB>
(wciśnięcie Ctrl-V, a następnie klawisza pisania)foo | awk '/\t/'
| awk '/\t/'
Rozwiązanie będzie działać dla wszystkich muszli, platform i systemów.
awk
działa tutaj dobrze, ale w niektórych testach na moim komputerze z bardzo dużymi plikami jest o około 30% wolniejszy niż przy użyciu grep -P
. Może to być trywialne i nieistotne w zależności od przypadku użycia, a awk
może być po prostu lepsze ze względu na czytelność i przenośność.
Z tej odpowiedzi na Ask Ubuntu:
Powiedz grep, aby używał wyrażeń regularnych zdefiniowanych przez Perla (Perl ma
\t
jako tab):grep -P "\t" <file name>
Użyj dosłownego znaku tabulacji:
grep "^V<tab>" <filename>
Użyj,
printf
aby wydrukować znak tabulacji:grep "$(printf '\t')" <filename>
Jednym ze sposobów jest (dotyczy to Bash)
grep -P '\t'
-P
włącza wyrażenia regularne Perla, więc \ t będzie działać.
Jak mówi użytkownik odprężający , może być specyficzny dla GNU grep. Alternatywą jest dosłowne wstawienie tam karty, jeśli pozwala na to powłoka, edytor lub terminal.
Innym sposobem wstawiania tabulatora dosłownie wewnątrz wyrażenia jest użycie mniej znanego $'\t'
cytatu w Bash:
grep $'foo\tbar' # matches eg. 'foo<tab>bar'
(Pamiętaj, że jeśli dopasowujesz do ustalonych ciągów, możesz użyć tego w trybie „-F”).
Czasami użycie zmiennych może sprawić, że notacja będzie bardziej czytelna i łatwiejsza w zarządzaniu:
tab=$'\t' # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id" # matches eg. `bob2<tab>323`
Nie jest to dokładnie to, czego szukasz, ale może działać w twoim przypadku
grep '[[:blank:]]'
Równoważny
grep -P '[ \t]'
Więc znajdzie Spację i Tab.
Uwaga, to nie jest reklamowane w moim man grep
, ale nadal działa
$ man grep | grep blank | toaleta 0 0 0
-P
argument został dodany.
Istnieją zasadniczo dwa sposoby rozwiązania tego problemu:
( Zalecane ) Użyj składni wyrażeń regularnych obsługiwanych przez grep (1). Modern grep (1) obsługuje dwie formy składni wyrażenia regularnego POSIX 1003.2: podstawowe (przestarzałe) RE i nowoczesne RE. Składnia została szczegółowo opisana na stronach man re_format (7) i regex (7), które są odpowiednio częścią systemów BSD i Linux. GNU grep (1) obsługuje również RE zgodne z Perlem, zgodnie z biblioteką pcre (3).
W języku regularnym symbol tab jest zwykle kodowany przez \t
atom. Atom jest obsługiwany przez BSD rozszerzone wyrażenia regularne ( egrep
, grep -E
na BSD systemu kompatybilny), a także Perl kompatybilnych RES ( pcregrep
GNU grep -P
).
Zarówno podstawowe wyrażenia regularne, jak i rozszerzone RE systemu Linux najwyraźniej nie obsługują \t
. Zajrzyj na stronę podręcznika narzędzia UNIX, aby dowiedzieć się, który język wyrażeń regularnych obsługuje (stąd różnica między wyrażeniami regularnymi sed (1), awk (1) i pcregrep (1)).
Dlatego w systemie Linux:
$ grep -P '\t' FILE ...
W systemie podobnym do BSD:
$ egrep '\t' FILE ...
$ grep -E '\t' FILE ...
Przekaż znak tabulacji do wzorca. Jest to proste, gdy edytujesz plik skryptu:
# no tabs for Python please!
grep -q ' ' *.py && exit 1
Jednak podczas pracy w interaktywnej powłoce konieczne może być skorzystanie z możliwości powłoki i terminala, aby wpisać odpowiedni symbol w linii. Na większości terminali można to zrobić za pomocą kombinacji klawiszy Ctrl
+ V
, która instruuje terminal, aby traktował następny znak wejściowy dosłownie ( V
jest to „dosłownie”):
$ grep '<Ctrl>+<V><TAB>' FILE ...
Niektóre powłoki mogą oferować zaawansowaną obsługę składu poleceń. Tak więc, w bash (1) słowa formularza $'string'
są traktowane specjalnie:
bash$ grep $'\t' FILE ...
Pamiętaj jednak, że chociaż jest miły w wierszu poleceń, może powodować problemy ze zgodnością, gdy skrypt zostanie przeniesiony na inną platformę. Zachowaj ostrożność przy korzystaniu z ofert specjalnych. Szczegółowe informacje znajdziesz w bash (1).
W przypadku powłoki Bourne'a (i nie tylko) to samo zachowanie może być emulowane za pomocą podstawiania poleceń wspomaganego przez printf (1) w celu skonstruowania odpowiedniego wyrażenia regularnego:
$ grep "`printf '\t'`" FILE ...
użyj gawk, ustaw ogranicznik pól na tab (\ t) i sprawdź liczbę pól. Jeśli więcej niż 1, to są / są zakładki
awk -F"\t" 'NF>1' file
awk /\t/
wystarcza na pytanie op.
Dobrym wyborem jest użycie „sed as grep” (jak wyjaśniono w tym klasycznym samouczku sed ).
sed -n 's/pattern/&/p' file
Przykłady (działa w bash, sh, ksh, csh, ..):
[~]$ cat testfile
12 3
1 4 abc
xa c
a c\2
1 23
[~]$ sed -n 's/\t/&/p' testfile
xa c
a c\2
[~]$ sed -n 's/\ta\t/&/p' testfile
a c\2
+1 sposób, który działa w ksh, myślniku itp: użyj printf, aby wstawić TAB:
grep "$(printf 'BEGIN\tEND')" testfile.txt
grep "$(printf '\t')" testfile.txt
Używanie metody „sed-as-grep”, ale zamiana zakładek na widoczny znak osobistych preferencji to moja ulubiona metoda, ponieważ wyraźnie pokazuje, które pliki zawierają żądane informacje, a także gdzie są umieszczone w liniach:
sed -n 's/\t/\*\*\*\*/g' file_name
Jeśli chcesz skorzystać z informacji o linii / pliku lub innych opcji grep, ale także chcesz zobaczyć widoczny zamiennik znaku tabulacji, możesz to osiągnąć poprzez
grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'
Jako przykład:
$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar
EDYCJA: Oczywiście powyższe jest przydatne tylko do przeglądania zawartości pliku w celu zlokalizowania kart --- jeśli celem jest obsługa kart w ramach większej sesji skryptowej, nie służy to żadnemu przydatnemu celowi.
Możesz użyć grep "$(echo -e '\t')"
Jedynym wymogiem jest echo
możliwość interpretacji ucieczek odwrotnego ukośnika.
Te alternatywne metody identyfikacji binarnej są całkowicie funkcjonalne. I naprawdę podoba mi się ten, który używa awk, ponieważ nie do końca pamiętam składniowe użycie pojedynczych znaków binarnych. Jednak powinno być również możliwe przypisanie zmiennej powłoki wartości w przenośny sposób POSIX (tj. TAB = echo "@" | tr "\100" "\011"
), a następnie zastosowanie jej stamtąd wszędzie, w przenośny sposób POSIX; jak również (tzn. nazwa pliku grep „$ TAB”). Chociaż to rozwiązanie działa dobrze z TAB, będzie również działać dobrze z innymi znakami binarnymi, gdy w przypisaniu zostanie użyta inna pożądana wartość binarna (zamiast wartości znaku TAB na „tr”).
Notacja $ '\ t' podana w innych odpowiedziach jest specyficzna dla powłoki - wydaje się, że działa w bash i zsh, ale nie jest uniwersalna.
UWAGA: Poniższe informacje dotyczą fish
powłoki i nie działają w trybie bash :
W fish
powłoce można użyć cudzysłowu \t
, na przykład:
grep \t foo.txt
Lub można użyć notacji szesnastkowych lub Unicode, np .:
grep \X09 foo.txt
grep \U0009 foo.txt
(te notacje są przydatne dla bardziej ezoterycznych postaci)
Ponieważ te wartości muszą być niecytowane, można łączyć wartości cytowane i niecytowane przez łączenie:
grep "foo"\t"bar"
Możesz pisać
grep \ t foo
grep '\ t' foo
aby wyszukać znak tabulatora w pliku foo. Prawdopodobnie możesz zrobić także inne kody ucieczki, chociaż tylko przetestowałem \ n. Chociaż jest to dość czasochłonne i niejasne, dlaczego chcesz, w zsh możesz także wpisać znak tabulacji, wróć na początek, grep i umieść kartę w cudzysłowie.
Szukaj pustych miejsc wiele razy [[: space:]] *
grep [[: space:]] * '.' '.'
Znajdziesz coś takiego:
'Zakładka' ..
Są to pojedyncze cudzysłowy ('), a nie podwójne (").
W ten sposób tworzysz konkatenację w grep. = -)
grep "<Ctrl+V><TAB>"
, to działa (jeśli pierwszy raz: wpisz,grep "
a następnie naciśnij kombinację klawiszy Ctrl + V, następnie naciśnij klawisz TAB, a następnie wpisz"
i naciśnij Enter, voilà!)