grep tab w UNIX


417

Jak greptabulować (\ t) w plikach na platformie Unix?


53
po prostu użyj 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à!)
gawron

16
ctrl + v to NAPRAWDĘ ZŁY POMYSŁ! ... tak, może działać z komendy konsoli, ale NIE MOŻE DZIAŁAĆ, ABY WTÓRZYĆ SIĘ W SKRÓCIE (jesteś na łasce edytora, na przykład używam mcedit i ctrl + v NIE pracuj tam)
THESorcerer


Zobacz także: askubuntu.com/questions/53071/… (również link poniżej)
shiri,

Odpowiedzi:


374

Jeśli używasz GNU grep, możesz użyć wyrażenia regularnego w stylu Perla:

grep -P '\t' *

To nie wydaje się działać wbrew mojemu wzorowi. Próba użycia tej składni nic nie powoduje. (Czy wariant Mac OS X jest inny?)
futureelite7

2
@futureelite: Według dokumentów Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/... ) program grep dla Mac OS X powinien obsługiwać opcję -P. Zastanów się nad utworzeniem nowego pytania na superuser.com.
zrelaksuj się

3
To bardzo dobrze dla GNU UNIX, ale co z POSIX Solaris, AIX i HP-UX? Nie wiedzą nic o -Popcji.
gawron

21
@rook GNU nie jest UNIX.
Lily Chung

5
w Mac OSX możesz podać wzór za pomocą -e
Faisal Feroz

314

Sztuką jest użycie znaku $ przed pojedynczymi cudzysłowami. Działa również do cięcia i innych narzędzi.

grep $'\t' sample.txt

7
Wskazówka Lifesavior ratuje życie! O zshile mi wiadomo, to również działa . Czy mógłbyś skomentować, co to jest semantyka tego $znaku?
Romain

2
Nie działa, jeśli ciąg zawiera coś innego niż „\ t”. Jak na przykład szukałbyś „\ t” (tab + spacja)?
Raman

6
Raman: Możesz użyć $'\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.
v6ak

5
Myślę, że $ '...' to idiotyczny idiom. Prawdopodobnie nie działa w sh. Nie wiem o csh lub tcsh.
Edward Falk

5
Z „man bash”: słowa w postaci $ „string” są traktowane specjalnie. Słowo jest interpretowane jako ciąg znaków, a znaki specjalne z odwrotnym ukośnikiem są zastępowane zgodnie ze standardem ANSI C. Sekwencje specjalne
odwrotnego ukośnika

84

Nigdy nie udało mi się sprawić, aby metaznak „\ t” działał z grep. Znalazłem jednak dwa alternatywne rozwiązania:

  1. Używanie <Ctrl-V> <TAB>(wciśnięcie Ctrl-V, a następnie klawisza pisania)
  2. Za pomocą awk: foo | awk '/\t/'

4
| awk '/\t/'Rozwiązanie będzie działać dla wszystkich muszli, platform i systemów.
Samveen,

6
+1 dla przenośnego rozwiązania POSIX i niestosowania bashism, zshism, GNUism i linuxism.
Jens

1
ctrl-V nie jest użyteczny, jeśli chcesz skopiować i wkleić (z notatek lub skryptu). Lepiej użyj jawnego rozwiązania, które ma widoczne „\ t”, dosłowne tabele (tj.
Te

awkdział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 awkmoże być po prostu lepsze ze względu na czytelność i przenośność.
theferrit32

43

Z tej odpowiedzi na Ask Ubuntu:

Powiedz grep, aby używał wyrażeń regularnych zdefiniowanych przez Perla (Perl ma \tjako tab):

grep -P "\t" <file name>

Użyj dosłownego znaku tabulacji:

grep "^V<tab>" <filename>

Użyj, printfaby wydrukować znak tabulacji:

grep "$(printf '\t')" <filename>


ctrl-V nie jest użyteczny, jeśli chcesz skopiować i wkleić (z notatek lub skryptu). Lepiej użyj jawnego rozwiązania, które ma widoczne „\ t”, dosłowne
tabele TAB

31

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.


Nieznana opcja P w powłoce ksh
Sachin Chourasiya

Jak mówiindind, może być specyficzne dla GNU grep. Właśnie wyjaśnione.
tjmoore,

Jak dodać kartę? Czy po naciśnięciu przycisku Tab nie rozpoczyna się proces autouzupełniania? (może to działać w skrypcie bash, ale nie w wierszu poleceń)
AntonioCS

1
@AntonioCS jak wspomniano powyżej przez SamKrieg, aby Shell mógł wpisać dowolny znak, po prostu wpisz CTRL-v jako pierwszy. Zobacz także askubuntu.com/questions/53071/…
Denis Arnaud

2
-P jest specyficzny dla grep, nie dla żadnej powłoki. -P powinien działać w dowolnej powłoce, pod warunkiem, że GNU grep jest zainstalowany
plijnzaad

13

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`

10

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.

§ Klasy postaci

Uwaga, to nie jest reklamowane w moim man grep, ale nadal działa

$ man grep | grep blank | toaleta
      0 0 0

@ A-letubby Działa teraz z edycją - -Pargument został dodany.
villapx


6

Istnieją zasadniczo dwa sposoby rozwiązania tego problemu:

  1. ( 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 \tatom. Atom jest obsługiwany przez BSD rozszerzone wyrażenia regularne ( egrep, grep -Ena BSD systemu kompatybilny), a także Perl kompatybilnych RES ( pcregrepGNU 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 ...
    
  2. 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 ( Vjest 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 ...
    


2

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

2
To trochę przesada i nie trafia w to pytanie. awk /\t/wystarcza na pytanie op.
Ograniczone Zadośćuczynienie

2

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

+1 sposób, który działa w ksh, myślniku itp: użyj printf, aby wstawić TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt

Nie działało to dla mnie w Ubuntu Trusty (Bash 4.3.11), jednak działały następujące czynności:grep "$(printf '\t')" testfile.txt
Josh Rumbut

0

Odpowiedź jest prostsza. Napisz grep i w cudzysłowie wpisz klawisz tab, działa to dobrze przynajmniej w ksh

grep "  " *

3
najpierw musisz wprowadzić znak TAB do swojej powłoki - większość powłok interpretuje ten klucz jako polecenie (zakończenie)
Kaii


0

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.


0

Działa to dobrze w systemie AIX. Szukam wierszy zawierającychJOINED<\t>ACTIVE

voradmin cluster status | grep  JOINED$'\t'ACTIVE

 vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE

0

Możesz użyć grep "$(echo -e '\t')"

Jedynym wymogiem jest echomożliwość interpretacji ucieczek odwrotnego ukośnika.


0

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”).


0

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ą fishpowłoki i nie działają w trybie bash :

W fishpowł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"

-4

Możesz pisać

grep \ t foo

lub

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.


-6

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. = -)

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.