ambil tab di UNIX

418

Bagaimana cara saya greptab (\ t) dalam file di platform Unix?

Sachin Chourasiya
sumber
53
cukup gunakan grep "<Ctrl+V><TAB>", ini berfungsi (jika pertama kali: ketik grep "lalu tekan Ctrl + V key combo, lalu tekan tombol TAB, lalu ketik "dan tekan enter, voila!)
rook
16
ctrl + v adalah IDE SANGAT BURUK! ... ya itu dapat bekerja dari perintah konsol, tetapi mungkin TIDAK BEKERJA UNTUK MENGETAHUI DALAM SCRIPT (Anda berada di bawah kendali editor, misalnya saya menggunakan mcedit dan ctrl + v JANGAN bekerja di sana)
THorcerer
Terkait, tetapi bukan duplikat: Cari tab, tanpa -P, menggunakan 'grep'
Peter Mortensen
Lihat juga: askubuntu.com/questions/53071/… (ditautkan di bawah ini juga)
shiri

Jawaban:

375

Jika menggunakan GNU grep, Anda dapat menggunakan reg-style Perl:

grep -P '\t' *
beristirahat
sumber
Sepertinya tidak berhasil melawan pola saya. Mencoba menggunakan sintaks itu tidak menghasilkan apa-apa. (Apakah varian Mac OS X berbeda?)
futureelite7
2
@futureelite: Menurut dokumen Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ), program grep Mac OS X harus mendukung opsi -P. Pertimbangkan untuk membuat pertanyaan baru, di superuser.com.
bersantai
3
Itu sangat bagus untuk GNU UNIX, tetapi bagaimana dengan POSIX Solaris, AIX dan HP-UX? Mereka tidak tahu apa-apa tentang -Popsi.
benteng
21
@rook GNU Bukan UNIX.
Lily Chung
5
di Mac OSX Anda dapat memberikan pola menggunakan -e
Faisal Feroz
314

Caranya adalah dengan menggunakan $ sign sebelum tanda kutip tunggal . Ini juga berfungsi untuk memotong dan alat lainnya.

grep $'\t' sample.txt
antimirov
sumber
7
Tip penyelamat menyelamatkan nyawa! Itu berhasil zshjuga, sejauh yang saya tahu. Bisakah Anda mengomentari apa semantik dari $tanda itu?
Romain
2
Tidak berfungsi jika String berisi apa pun selain '\ t'. Bagaimana Anda mencari "\ t" (tab + spasi) misalnya?
Raman
6
Raman: Anda bisa menggunakan $'\t'' '. Sebuah contoh nyata yang menunjukkan itu berfungsi juga dengan sh (bukan hanya bash, yang tidak secara default diinstal pada Android) adalah busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak
5
Saya pikir $ '...' adalah ungkapan bash. Mungkin tidak bekerja di sh. Tidak tahu tentang csh atau tcsh.
Edward Falk
5
Dari 'man bash': Kata-kata dalam bentuk $ 'string' diperlakukan secara khusus. Kata diperluas ke string, dengan karakter backslash-escaped diganti sebagaimana ditentukan oleh standar ANSI C. Urutan melarikan diri garis miring terbalik, jika ada, diterjemahkan ...
broeni
84

Saya tidak pernah berhasil membuat metacharacter '\' bekerja dengan grep. Namun saya menemukan dua solusi alternatif:

  1. Menggunakan <Ctrl-V> <TAB>(menekan Ctrl-V lalu mengetik tab)
  2. Menggunakan awk: foo | awk '/\t/'
SamK
sumber
4
The | awk '/\t/'solusi akan bekerja untuk semua kerang, platform dan sistem.
Samveen
6
+1 untuk solusi POSIX portabel dan tidak menggunakan bashism, zshism, GNUism, dan linuxisms.
Jens
1
ctrl-V tidak berguna jika Anda ingin menyalin-menempel (dari catatan atau skrip Anda). Lebih baik menggunakan solusi eksplisit yang memiliki TAB literal yang terlihat 't', (yaitu yang terlihat seperti spasi) sering dikonversi ke SPC ketika
menyalin
awkberfungsi dengan baik di sini tetapi dalam beberapa pengujian pada komputer saya dengan file yang sangat besar itu sekitar 30% lebih lambat daripada menggunakan grep -P. Ini mungkin sepele dan tidak relevan berdasarkan use case, dan awkmungkin lebih baik hanya untuk keterbacaan dan portabilitas.
theferrit32
43

Dari jawaban ini di Tanya Ubuntu:

Katakan grep untuk menggunakan ekspresi reguler seperti yang didefinisikan oleh Perl (Perl memiliki \tsebagai tab):

grep -P "\t" <file name>

Gunakan karakter tab literal:

grep "^V<tab>" <filename>

Gunakan printfuntuk mencetak karakter tab untuk Anda:

grep "$(printf '\t')" <filename>
Sial
sumber
1
Verbatim dari http://askubuntu.com/a/53096/453741
villapx
ctrl-V tidak berguna jika Anda ingin menyalin-menempel (dari catatan atau skrip Anda). Lebih baik menggunakan solusi eksplisit yang memiliki TAB literal yang terlihat 't', (yaitu yang terlihat seperti spasi) sering dikonversi ke SPC ketika
menyalin
31

Salah satu caranya adalah (ini dengan Bash)

grep -P '\t'

-P Mengaktifkan Perl ekspresi reguler sehingga \ t akan bekerja.

Sebagai pengguna bersantai mengatakan, itu mungkin khusus untuk GNU grep. Alternatifnya adalah dengan memasukkan tab di sana jika shell, editor atau terminal mengizinkannya.

tjmoore
sumber
Opsi P tidak dikenal dalam shell ksh
Sachin Chourasiya
Seperti kata santai, mungkin spesifik untuk GNU grep. Baru saja diklarifikasi.
tjmoore
Bagaimana Anda menambahkan tab? Apakah itu tidak memulai proses penyelesaian otomatis ketika Anda menekan tombol tab? (yang mungkin bekerja dalam skrip bash tetapi tidak pada baris perintah)
AntonioCS
1
@AntonioCS seperti yang disebutkan di atas oleh SamKrieg, agar Shell membiarkan Anda mengetik karakter apa pun, cukup ketik CTRL-v terlebih dahulu. Lihat juga askubuntu.com/questions/53071/...
Denis Arnaud
2
-P khusus untuk grep, bukan untuk shell apa pun. -P harus bekerja di shell apa saja, asalkan GNU grep diinstal
plijnzaad
13

Cara lain untuk menyisipkan tab secara harfiah di dalam ekspresi adalah dengan menggunakan $'\t'kutipan yang kurang dikenal di Bash:

grep $'foo\tbar'        # matches eg. 'foo<tab>bar'

(Perhatikan bahwa jika Anda cocok dengan string tetap, Anda dapat menggunakan ini dengan mode '-F'.)

Terkadang menggunakan variabel dapat membuat notasi sedikit lebih mudah dibaca dan dikelola:

tab=$'\t'               # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id"     # matches eg. `bob2<tab>323`
Alois Mahdal
sumber
10

Ini bukan apa yang Anda cari, tetapi mungkin berhasil dalam kasus Anda

grep '[[:blank:]]'

Setara dengan

grep -P '[ \t]'

Sehingga akan menemukan Space dan Tab.

§ Kelas karakter

Catatan, ini tidak diiklankan di saya man grep, tetapi masih berfungsi

$ man grep | grep blank | toilet
      0 0 0
Steven Penny
sumber
@ A-letubby Sekarang berfungsi dengan hasil edit - -Pargumen telah ditambahkan.
villapx
6

Gunakan gema untuk menyisipkan tab untuk Anda grep "$(echo -e \\t)"

Vanjoe
sumber
6

Pada dasarnya ada dua cara untuk mengatasinya:

  1. ( Disarankan ) Gunakan sintaks ekspresi reguler yang didukung oleh grep (1). Modern grep (1) mendukung dua bentuk sintaks regex POSIX 1003.2: REs dasar (usang) RE, dan RE modern . Sintaks dijelaskan secara rinci pada halaman manual re_format (7) dan regex (7) yang masing-masing merupakan bagian dari sistem BSD dan Linux. GNU grep (1) juga mendukung RE yang kompatibel dengan Perl sebagaimana disediakan oleh pustaka pcre (3).

    Dalam bahasa regex, simbol tab biasanya dikodekan oleh \tatom. Atom ini didukung oleh BSD yang berekspresi reguler yang diperluas ( egrep, grep -Epada sistem yang kompatibel dengan BSD), serta RE yang kompatibel dengan Perl ( pcregrep, GNU grep -P).

    Ekspresi reguler dasar dan RE yang diperpanjang Linux tampaknya tidak memiliki dukungan untuk \t. Silakan baca halaman utilitas UNIX untuk mengetahui bahasa regex mana yang didukungnya (karenanya perbedaan antara sed (1), awk (1), dan pcregrep (1) ekspresi reguler).

    Oleh karena itu, di Linux:

    $ grep -P '\t' FILE ...
    

    Pada sistem BSD yang serupa:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Masukkan karakter tab ke dalam pola. Ini mudah ketika Anda mengedit file skrip:

    # no tabs for Python please!
    grep -q '   ' *.py && exit 1
    

    Namun, ketika bekerja di shell interaktif Anda mungkin perlu mengandalkan shell dan kemampuan terminal untuk mengetik simbol yang tepat ke dalam garis. Pada sebagian besar terminal, ini dapat dilakukan melalui kombinasi Ctrl+ Vkunci yang menginstruksikan terminal untuk memperlakukan karakter input berikutnya secara harfiah ( Vuntuk "verbatim"):

    $ grep '<Ctrl>+<V><TAB>' FILE ...
    

    Beberapa shell mungkin menawarkan dukungan tingkat lanjut untuk pengaturan huruf perintah. Seperti itu, dalam bash (1) kata-kata dari form $'string'diperlakukan secara khusus:

    bash$ grep $'\t' FILE ...
    

    Harap dicatat, meskipun bersikap baik di baris perintah, ini dapat menghasilkan masalah kompatibilitas ketika skrip akan dipindahkan ke platform lain. Juga, berhati-hatilah dengan penawaran ketika menggunakan penawaran spesial, silakan berkonsultasi dengan bash (1) untuk detailnya.

    Untuk shell Bourne (dan tidak hanya) perilaku yang sama dapat ditiru menggunakan substitusi perintah ditambah oleh printf (1) untuk membangun regex yang tepat:

    $ grep "`printf '\t'`" FILE ...
    
Mike Volokhov
sumber
4

grep "$(printf '\t')" bekerja untuk saya di Mac OS X

kumar303
sumber
2

gunakan gawk, atur pembatas bidang ke tab (\ t) dan periksa jumlah bidang. Jika lebih dari 1, maka ada tab

awk -F"\t" 'NF>1' file
ghostdog74
sumber
2
Ini agak berlebihan, dan melewatkan pertanyaan. awk /\t/sudah cukup untuk pertanyaan op.
Penebusan Terbatas
2

Pilihan yang baik adalah menggunakan 'sed as grep' (seperti yang dijelaskan dalam tutorial sed klasik ini ).

sed -n 's/pattern/&/p' file

Contoh (berfungsi dalam 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
Julio
sumber
1

Cara +1, yang bekerja di ksh, dash, dll: gunakan printf untuk memasukkan TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt
Zsigmond Lőrinczy
sumber
Ini tidak berfungsi untuk saya di Ubuntu Trusty (Bash 4.3.11), berikut ini berhasil meskipun:grep "$(printf '\t')" testfile.txt
Josh Rumbut
0

Jawabannya lebih sederhana. Tulis grep Anda dan dalam kutipan ketik tombol tab, itu berfungsi dengan baik setidaknya dalam ksh

grep "  " *
YullyBear
sumber
3
pertama, Anda perlu mengatur untuk memasukkan karakter TAB di shell Anda - sebagian besar shell mengartikan kunci ini sebagai perintah (selesai)
Kaii
0

Pada ksh saya gunakan

grep "[^I]" testfile
AIXroot
sumber
0

Menggunakan metode 'sed-as-grep', tetapi mengganti tab dengan karakter preferensi pribadi yang terlihat adalah metode favorit saya, karena ini menunjukkan dengan jelas file mana yang berisi info yang diminta, dan juga di mana ia ditempatkan dalam baris:

sed -n 's/\t/\*\*\*\*/g' file_name

Jika Anda ingin memanfaatkan informasi baris / file, atau opsi grep lainnya, tetapi juga ingin melihat penggantian yang terlihat untuk karakter tab, Anda dapat mencapainya dengan

grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'

Sebagai contoh:

$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar

EDIT: Jelas di atas hanya berguna untuk melihat konten file untuk menemukan tab --- jika tujuannya adalah untuk menangani tab sebagai bagian dari sesi skrip yang lebih besar, ini tidak melayani tujuan yang bermanfaat.

Silasvb
sumber
0

Ini bekerja dengan baik untuk AIX. Saya mencari baris yang berisiJOINED<\t>ACTIVE

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

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

Anda mungkin ingin menggunakan grep "$(echo -e '\t')"

Hanya persyaratan yang echoharus mampu menafsirkan lolos backslash.

kshpolvind
sumber
0

Metode identifikasi biner alternatif ini sepenuhnya fungsional. Dan, saya sangat suka yang menggunakan awk, karena saya tidak begitu ingat penggunaan sintaksis dengan karakter biner tunggal. Namun, itu juga harus mungkin untuk menetapkan variabel shell nilai dalam mode portabel POSIX (yaitu TAB = echo "@" | tr "\100" "\011"), dan kemudian menggunakannya dari sana di mana-mana, dalam mode portabel POSIX; juga (mis. grep "$ TAB" nama file). Sementara solusi ini bekerja dengan baik dengan TAB, itu juga akan bekerja dengan baik karakter biner lainnya, ketika nilai biner lain yang diinginkan digunakan dalam tugas (bukan nilai untuk karakter TAB untuk 'tr').

odoncaoa
sumber
0

Notasi $ '\ t' yang diberikan dalam jawaban lain khusus untuk shell - tampaknya berfungsi dalam bash dan zsh tetapi tidak universal.

CATATAN: Berikut ini untuk fishshell dan tidak bekerja di bash :

Dalam fishshell, seseorang dapat menggunakan tanda kutip \t, misalnya:

grep \t foo.txt

Atau seseorang dapat menggunakan notasi hex atau unicode misalnya:

grep \X09 foo.txt
grep \U0009 foo.txt

(notasi ini berguna untuk karakter yang lebih esoteris)

Karena nilai-nilai ini harus tidak dikutip, seseorang dapat menggabungkan nilai-nilai yang dikutip dan tidak dikutip oleh gabungan:

grep "foo"\t"bar"
Raman
sumber
-4

Anda bisa mengetik

grep \ t foo

atau

grep 't foo

untuk mencari karakter tab di file foo. Anda mungkin juga dapat melakukan kode pelarian lainnya, meskipun saya baru menguji \ n. Meskipun agak memakan waktu, dan tidak jelas mengapa Anda ingin, di zsh Anda juga dapat mengetikkan karakter tab, kembali ke awal, ambil dan tutupi tab dengan tanda kutip.

Air asin yang tidak disengaja
sumber
-6

Carilah ruang kosong berkali-kali [[: spasi:]] *

grep [[: space:]] * '.' '.'

Akan menemukan sesuatu seperti ini:

'tab' ..

Ini adalah kutipan tunggal ('), dan bukan dua kali lipat (").
Ini adalah bagaimana Anda membuat rangkaian dalam grep. = -)

Caio Argolo
sumber