grep một tab trong UNIX


418

Làm cách nào để tôi greptab (\ t) trong các tệp trên nền tảng Unix?


53
chỉ cần sử dụng grep "<Ctrl+V><TAB>", nó hoạt động (nếu lần đầu tiên: gõ grep "rồi nhấn tổ hợp phím Ctrl + V, sau đó nhấn phím TAB, sau đó nhập "và nhấn enter, voilà!)
rook

16
ctrl + v là một IDEA BAD THỰC SỰ! ... vâng, nó có thể hoạt động từ lệnh console, nhưng nó có thể KHÔNG LÀM VIỆC ĐỂ KIẾM ĐƯỢC NÓ TRONG MỘT SCRIPT (bạn đang thương xót trình soạn thảo, ví dụ tôi sử dụng mcedit và ctrl + v KHÔNG làm việc ở đó)
THESorcerer


Xem thêm: Askubfox.com/questions/53071/ (cũng được liên kết bên dưới)
shiri

Câu trả lời:


375

Nếu sử dụng GNU grep, bạn có thể sử dụng biểu thức chính quy theo kiểu Perl:

grep -P '\t' *

Nó dường như không hoạt động chống lại mô hình của tôi. Cố gắng sử dụng cú pháp đó in không có gì. (Biến thể Mac OS X có khác không?)
Futureelite7

2
@futureelite: Theo tài liệu của Apple ( developer.apple.com/Mac/l Library / documentation / Darwin / Reference / / ), chương trình grep Mac OS X sẽ hỗ trợ tùy chọn -P. Xem xét việc tạo một câu hỏi mới, trên superuser.com.
thư giãn

3
Điều đó rất tốt cho GNU UNIX, nhưng còn POSIX Solaris, AIX và HP-UX thì sao? Những người không biết gì về -Plựa chọn.
rook

21
@rook GNU không phải là UNIX.
Lily Chung

5
trong Mac OSX, bạn có thể đưa ra mô hình bằng cách sử dụng -e
Faisal Feroz

314

Bí quyết là sử dụng dấu $ trước dấu ngoặc đơn . Nó cũng hoạt động để cắt và các công cụ khác.

grep $'\t' sample.txt

7
Mẹo cứu người cứu mạng! Nó cũng hoạt động zshtốt, như tôi có thể nói. Bạn có thể nhận xét về ngữ nghĩa của $dấu hiệu đó là gì?
Romain

2
Không hoạt động nếu Chuỗi chứa bất cứ thứ gì ngoài '\ t'. Làm thế nào bạn sẽ tìm kiếm "\ t" (tab + dấu cách) chẳng hạn?
Raman

6
Raman: Bạn có thể sử dụng $'\t'' '. Một ví dụ thực tế cho thấy nó cũng hoạt động với sh (không chỉ bash, không được cài đặt mặc định trên Android) busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak

5
Tôi nghĩ $ '...' là một thành ngữ bash. Có lẽ không làm việc trong sh. Dunno về csh hoặc tcsh.
Edward Falk

5
Từ 'man bash': Các từ có dạng $ 'chuỗi' được xử lý đặc biệt. Từ này mở rộng thành chuỗi, với các ký tự thoát dấu gạch chéo ngược được thay thế theo quy định của tiêu chuẩn ANSI C. Các chuỗi thoát dấu gạch chéo ngược, nếu có, được giải mã ...
broeni

84

Tôi chưa bao giờ quản lý để làm cho vi khuẩn '\ t' hoạt động với grep. Tuy nhiên tôi tìm thấy hai giải pháp thay thế:

  1. Sử dụng <Ctrl-V> <TAB>(nhấn Ctrl-V sau đó gõ tab)
  2. Sử dụng awk: foo | awk '/\t/'

4
Các | awk '/\t/'giải pháp sẽ làm việc cho tất cả vỏ, nền tảng và hệ thống.
Samveen

6
+1 cho giải pháp POSIX di động và không sử dụng bashism, zshism, GNUism và linuxism.
Jens

1
ctrl-V không hữu ích nếu bạn muốn sao chép-dán (từ ghi chú của bạn hoặc tập lệnh). Sử dụng tốt hơn một giải pháp rõ ràng có 'T t' rõ ràng, các TAB theo nghĩa đen (nghĩa là các TAB trông giống như khoảng trắng) thường được chuyển đổi sang SPC khi sao chép ...
plijnzaad

awkhoạt động tốt ở đây nhưng trong một số thử nghiệm trên máy của tôi với các tệp rất lớn thì chậm hơn khoảng 30% so với sử dụng grep -P. Điều này có thể là tầm thường và không liên quan dựa trên trường hợp sử dụng, và awkcó thể tốt hơn chỉ đơn giản là cho khả năng đọc và tính di động.
theferrit32

43

Từ câu trả lời này trên Hỏi Ubuntu:

Yêu cầu grep sử dụng các biểu thức chính quy theo định nghĩa của Perl (Perl có \tdưới dạng tab):

grep -P "\t" <file name>

Sử dụng ký tự tab theo nghĩa đen:

grep "^V<tab>" <filename>

Sử dụng printfđể in một ký tự tab cho bạn:

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


ctrl-V không hữu ích nếu bạn muốn sao chép-dán (từ ghi chú của bạn hoặc tập lệnh). Sử dụng tốt hơn một giải pháp rõ ràng có 'T t' rõ ràng, các TAB theo nghĩa đen (nghĩa là các TAB trông giống như khoảng trắng) thường được chuyển đổi sang SPC khi sao chép
plijnzaad

31

Một cách là (đây là với Bash)

grep -P '\t'

-P bật biểu thức chính quy Perl để \ t sẽ hoạt động.

Như người dùng thư giãn nói, nó có thể đặc trưng cho GNU grep. Cách khác là chèn một tab vào đó nếu shell, trình soạn thảo hoặc thiết bị đầu cuối sẽ cho phép nó.


Tùy chọn P không xác định trong vỏ ksh
Sachin Chourasiya

Như thư giãn nói, có thể là cụ thể cho GNU grep. Chỉ cần làm rõ.
tjmoore

Làm thế nào để bạn thêm một tab? Nó không bắt đầu quá trình tự động hoàn thành khi bạn nhấn nút tab? (có thể hoạt động trong tập lệnh bash nhưng không phải trong dòng lệnh)
AntonioCS

1
@AntonioCS như SamKrieg đã lưu ý ở trên, để có Shell cho phép bạn nhập bất kỳ ký tự nào, chỉ cần nhập CTRL-v trước. Xem thêm Askubfox.com/questions/53071/ Mạnh
Denis Arnaud

2
-P là đặc trưng cho grep, không phải cho bất kỳ shell. -P nên hoạt động trong mọi shell, với điều kiện GNU grep được cài đặt
plijnzaad

13

Một cách khác để chèn tab theo nghĩa đen bên trong biểu thức là sử dụng $'\t'trích dẫn ít được biết đến trong Bash:

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

(Lưu ý rằng nếu bạn khớp với các chuỗi cố định, bạn có thể sử dụng chế độ này với chế độ '-F'.)

Đôi khi sử dụng các biến có thể làm cho ký hiệu dễ đọc và dễ quản lý hơn một chút:

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

10

Đây không phải là chính xác những gì bạn đang tìm kiếm, nhưng có thể hoạt động trong trường hợp của bạn

grep '[[:blank:]]'

Tương đương với

grep -P '[ \t]'

Vì vậy, nó sẽ tìm thấy Space và Tab.

§ Lớp nhân vật

Lưu ý, nó không được quảng cáo trong tôi man grep, nhưng vẫn hoạt động

$ man grep | grep trống | wc
      0 0 0

@ A-letubby Bây giờ nó hoạt động với chỉnh sửa - -Pđối số đã được thêm vào.
Villapx

6

Sử dụng echo để chèn tab cho bạn grep "$(echo -e \\t)"


6

Về cơ bản có hai cách để giải quyết nó:

  1. ( Khuyến nghị ) Sử dụng cú pháp biểu thức chính quy được hỗ trợ bởi grep (1). Modern grep (1) hỗ trợ hai dạng cú pháp regex POSIX 1003.2: REs cơ bản (lỗi thời) và REs hiện đại . Cú pháp được mô tả chi tiết trên các trang man re_format (7) và regex (7) là một phần của hệ thống BSD và Linux tương ứng. GNU grep (1) cũng hỗ trợ RE tương thích với Perl do thư viện pcre (3) cung cấp.

    Trong ngôn ngữ regex, biểu tượng tab thường được mã hóa bởi \tnguyên tử. Nguyên tử được hỗ trợ bởi các biểu thức chính quy mở rộng BSD ( egrep, grep -Etrên hệ thống tương thích BSD), cũng như REs tương thích Perl ( pcregrep, GNU grep -P).

    Cả hai biểu thức chính quy cơ bản và REs mở rộng của Linux dường như không hỗ trợ cho \t. Vui lòng tham khảo trang hướng dẫn tiện ích UNIX để biết ngôn ngữ regex nào hỗ trợ (do đó có sự khác biệt giữa sed (1), awk (1) và pcregrep (1) biểu thức chính quy).

    Do đó, trên Linux:

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

    Trên hệ thống BSD như nhau:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Truyền ký tự tab thành mẫu. Điều này rất đơn giản khi bạn chỉnh sửa tệp tập lệnh:

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

    Tuy nhiên, khi làm việc trong trình bao tương tác, bạn có thể cần phải dựa vào khả năng của trình bao và thiết bị đầu cuối để nhập ký hiệu phù hợp vào dòng. Trên hầu hết các thiết bị đầu cuối, điều này có thể được thực hiện thông qua tổ hợp phím Ctrl+ Vhướng dẫn thiết bị đầu cuối xử lý ký tự đầu vào tiếp theo theo nghĩa đen (nghĩa Vlà "nguyên văn"):

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

    Một số shell có thể cung cấp hỗ trợ nâng cao cho việc sắp chữ lệnh. Chẳng hạn, trong bash (1) các từ có dạng $'string'được xử lý đặc biệt:

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

    Mặc dù vậy, xin lưu ý, trong khi tốt trong một dòng lệnh, điều này có thể tạo ra các vấn đề tương thích khi tập lệnh sẽ được chuyển sang nền tảng khác. Ngoài ra, hãy cẩn thận với dấu ngoặc kép khi sử dụng sản phẩm đặc biệt, vui lòng tham khảo bash (1) để biết chi tiết.

    Đối với shell Bourne (và không chỉ), hành vi tương tự có thể được mô phỏng bằng cách sử dụng thay thế lệnh được tăng cường bởi printf (1) để xây dựng regex thích hợp:

    $ grep "`printf '\t'`" FILE ...
    


2

sử dụng gawk, đặt dấu phân cách trường thành tab (\ t) và kiểm tra số lượng trường. Nếu có nhiều hơn 1, thì có / là các tab

awk -F"\t" 'NF>1' file

2
Đây là một chút quá mức, và bỏ lỡ câu hỏi. awk /\t/là đủ cho câu hỏi của op.
Chuộc tội có giới hạn

2

Một lựa chọn tốt là sử dụng 'sed as grep' (như được giải thích trong hướng dẫn sed cổ điển này ).

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

Ví dụ (hoạt động trong 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

Cách +1, hoạt động trong ksh, dash, v.v .: sử dụng printf để chèn TAB:

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

Điều này không hoạt động với tôi trên Ubuntu Trusty (Bash 4.3.11), những điều sau đây đã hoạt động:grep "$(printf '\t')" testfile.txt
Josh Rumbut

0

Câu trả lời đơn giản hơn. Viết grep của bạn và trong loại trích dẫn, phím tab, nó hoạt động tốt ít nhất là trong ksh

grep "  " *

3
trước tiên, bạn cần quản lý để nhập một ký tự TAB trong trình bao của mình - hầu hết các trình bao diễn giải khóa này là một lệnh (hoàn thành)
Kaii


0

Sử dụng phương pháp 'sed-as-grep', nhưng thay thế các tab bằng ký tự hiển thị của sở thích cá nhân là phương pháp ưa thích của tôi, vì nó hiển thị rõ ràng cả tệp nào chứa thông tin được yêu cầu và cũng được đặt trong dòng:

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

Nếu bạn muốn sử dụng thông tin dòng / tệp hoặc các tùy chọn grep khác, nhưng cũng muốn xem thay thế hiển thị cho ký tự tab, bạn có thể đạt được điều này bằng cách

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

Ví dụ:

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

EDIT: Rõ ràng ở trên chỉ hữu ích cho việc xem nội dung tệp để định vị các tab --- nếu mục tiêu là xử lý các tab như một phần của phiên kịch bản lớn hơn, điều này không phục vụ bất kỳ mục đích hữu ích nào.


0

Điều này hoạt động tốt cho AIX. Tôi đang tìm kiếm các dòng có chứaJOINED<\t>ACTIVE

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

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

0

Bạn có thể muốn sử dụng grep "$(echo -e '\t')"

Chỉ yêu cầu là echocó khả năng giải thích các dấu gạch chéo ngược.


0

Những phương pháp nhận dạng nhị phân thay thế là hoàn toàn chức năng. Và, tôi thực sự thích một người sử dụng awk, vì tôi không thể nhớ được cách sử dụng cú pháp với các ký tự nhị phân đơn. Tuy nhiên, cũng có thể gán một biến shell một giá trị theo kiểu di động POSIX (tức là TAB = echo "@" | tr "\100" "\011"), và sau đó sử dụng nó từ mọi nơi, theo kiểu di động POSIX; cũng như (tên tệp grep "$ TAB"). Mặc dù giải pháp này hoạt động tốt với TAB, nhưng nó cũng sẽ hoạt động tốt với các ký tự nhị phân khác, khi một giá trị nhị phân mong muốn khác được sử dụng trong phép gán (thay vì giá trị cho ký tự TAB thành 'tr').


0

Ký hiệu $ '\ t' được đưa ra trong các câu trả lời khác là đặc trưng cho vỏ - nó dường như hoạt động trong bash và zsh nhưng không phổ biến.

LƯU Ý: Dưới đây là dành cho fishshell và không hoạt động trong bash :

Trong fishshell, người ta có thể sử dụng một trích dẫn \t, ví dụ:

grep \t foo.txt

Hoặc người ta có thể sử dụng các ký hiệu hex hoặc unicode, ví dụ:

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

(những ký hiệu này hữu ích cho các ký tự bí truyền hơn)

Vì các giá trị này phải được bỏ trích dẫn, người ta có thể kết hợp các giá trị được trích dẫn và không trích dẫn bằng cách ghép:

grep "foo"\t"bar"

-4

Bạn có thể gõ

grep \ t foo

hoặc là

grep '\ t' foo

để tìm kiếm ký tự tab trong tệp foo. Bạn có thể cũng có thể thực hiện các mã thoát khác, mặc dù tôi chỉ thử nghiệm \ n. Mặc dù việc này khá tốn thời gian và không rõ lý do tại sao bạn muốn, trong zsh, bạn cũng có thể nhập ký tự tab, quay lại từ đầu, grep và kèm theo tab với dấu ngoặc kép.


-6

Tìm khoảng trống nhiều lần [[: dấu cách:]] *

grep [[: dấu cách:]] * '.' '.'

Sẽ tìm thấy một cái gì đó như thế này:

'tab' ..

Đây là những trích dẫn đơn (') và không gấp đôi (").
Đây là cách bạn thực hiện ghép trong grep. = -)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.