UNIX'te bir sekme grep


417

grepUnix platformundaki dosyalarda nasıl sekme yapabilirim (\ t)?


53
sadece kullanın grep "<Ctrl+V><TAB>", işe yarıyor (eğer ilk seferinde: yazın, grep "sonra Ctrl + V tuş bileşimine basın, sonra SEKME tuşuna basın, sonra "enter ve voilà yazın ve basın !)
rook

16
ctrl + v GERÇEKTEN KÖTÜ BİR FİKİR! ... evet konsol komutundan çalışabilir, ancak bir SCRIPT'DE TİP ETMEYE ÇALIŞMAYABİLİR (editörün merhametindesiniz, örneğin mcedit ve ctrl + v kullanıyorum orada çalışmayın)
THESorcerer


Ayrıca bakınız: askubuntu.com/questions/53071/… (aşağıda da bağlantılı)
shiri

Yanıtlar:


374

GNU grep kullanıyorsanız, Perl tarzı normal ifadeyi kullanabilirsiniz:

grep -P '\t' *

Benim desenime aykırı görünüyor. Bu sözdizimini kullanmaya çalışmak hiçbir şey yazdırmaz. (Mac OS X varyantı farklı mı?)
futureelite7

2
@futureelite: Apple'ın belgelerine ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ) göre, Mac OS X grep programı -P seçeneğini desteklemelidir. Superuser.com'da yeni bir soru oluşturmayı düşünün.
gevşeyin

3
Bu GNU UNIX için çok iyi, ama POSIX Solaris, AIX ve HP-UX ne olacak? Bunlar -Pseçenek hakkında hiçbir şey bilmiyorlar .
kale

21
@rook GNU UNIX Değil.
Lily Chung

5
Mac OSX'te -e
Faisal Feroz

314

Hüner, tek tırnak işaretlerinden önce $ işaretini kullanmaktır . Aynı zamanda kesme ve diğer aletler için de kullanılabilir.

grep $'\t' sample.txt

7
Hayat kurtarıcı ipucu hayat kurtarır! Anlayabildiğim zshkadarıyla da işe yarıyor . Bu $işaretin anlambilimi hakkında yorum yapabilir misiniz ?
Romain

2
Dize '\ t' dışında bir şey içeriyorsa çalışmaz. Örneğin "\ t" (sekme + boşluk) için nasıl arama yaparsınız?
Raman

6
Raman: Kullanabilirsin $'\t'' '. Sh ile de çalıştığını gösteren gerçek bir örnek (sadece varsayılan olarak Android'de yüklü olmayan bash değil) busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak

5
Bence $ '...' bir bash deyimidir. Muhtemelen sh'de çalışmaz. Csh veya tcsh hakkında bilmiyorum.
Edward Falk

5
'Man bash': $ 'string' biçimindeki kelimeler özel olarak ele alınır. Sözcük dizeye genişler, ters eğik çizgiden kaçan karakterler ANSI C standardında belirtildiği gibi değiştirilir. Ters
eğik çizgi

84

Asla '\ t' metakarakterinin grep ile çalışmasını sağlayamadım. Ancak iki alternatif çözüm buldum:

  1. Kullanımı <Ctrl-V> <TAB>(isabet Ctrl-V sonra tab yazarak)
  2. Awk kullanma: foo | awk '/\t/'

4
| awk '/\t/'Çözümün bütün kabuklar, platformlar ve sistemler için çalışacaktır.
Samveen

6
Taşınabilir POSIX çözümü için +1 ve bashisms, zshism, GNUism ve linuxizmleri kullanmayın.
Jens

1
ctrl-V (notlarınızdan veya komut dosyasından) kopyalayıp yapıştırmak istiyorsanız yararlı değildir. Görünür bir '\ t', değişmez TAB'ları (yani boşluk gibi görünen) olan açık bir çözüm kullanıldığında, kopya yapıştırma sırasında genellikle SPC'ye dönüştürülür ...
plijnzaad

awkburada iyi çalışıyor ama çok büyük dosyaları olan makinemdeki bazı testlerde kullanmaktan yaklaşık% 30 daha yavaş grep -P. Bu, kullanım durumuna göre önemsiz ve alakasız awkolabilir ve sadece okunabilirlik ve taşınabilirlik için daha iyi olabilir.
theferrit32

43

Gönderen bu cevap Ubuntu Ask tarih:

Grep'e Perl tarafından tanımlanan normal ifadeleri kullanmasını söyleyin (Perl \tsekmesi vardır):

grep -P "\t" <file name>

Değişmez sekme karakterini kullanın:

grep "^V<tab>" <filename>

printfSizin için bir sekme karakteri yazdırmak için kullanın :

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


ctrl-V (notlarınızdan veya komut dosyasından) kopyalayıp yapıştırmak istiyorsanız yararlı değildir. Görünür bir '\ t', değişmez SEKME (yani boşluk gibi görünen) olan açık bir çözüm kullanıldığında, kopya
yapıştırma

31

Bir yol (bu Bash ile)

grep -P '\t'

-P Perl düzenli ifadelerini açar, böylece \ t çalışacaktır.

Kullanıcının gevşemesi söylediği gibi, GNU grep'e özgü olabilir. Alternatif, eğer kabuk, editör veya terminal buna izin veriyorsa, kelimenin tam anlamıyla bir sekme eklemektir.


Ksh kabuğunda bilinmeyen P seçeneği
Sachin Chourasiya

Gevşeyin dediği gibi GNU grep'e özgü olabilir. Sadece açıklığa kavuştum.
tjmoore

Nasıl sekme eklersiniz? Sekme düğmesine bastığınızda otomatik tamamlama işlemini başlatmıyor mu? (bu bir bash betiğinde çalışabilir, ancak komut satırında çalışmayabilir)
AntonioCS

1
@AntonioCS, SamKrieg tarafından yukarıda belirtildiği gibi, Shell'in herhangi bir karakteri yazmanıza izin vermesi için önce CTRL-v yazın. Ayrıca bkz. Askubuntu.com/questions/53071/…
Denis Arnaud

2
-P, herhangi bir kabuğa değil, grep'e özgüdür. -P GNU grep kurulu ise herhangi bir kabukta çalışmalıdır
plijnzaad

13

Sekmeyi kelimenin tam anlamıyla ifadenin içine eklemenin başka bir yolu, Bash'te daha az bilinen $'\t'alıntıyı kullanmaktır :

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

(Sabit dizelerle eşleşiyorsanız bunu '-F' modunda kullanabileceğinizi unutmayın.)

Bazen değişkenleri kullanmak gösterimi biraz daha okunabilir ve yönetilebilir hale getirebilir:

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

10

Bu tam olarak aradığınız şey değil, ancak sizin durumunuzda işe yarayabilir

grep '[[:blank:]]'

Eşittir

grep -P '[ \t]'

Böylece Space ve Tab bulacaktır.

§ Karakter sınıfları

Not, benim reklamı değil man grep, ama yine de çalışıyor

$ erkek grep | grep boş | tuvalet
      0 0 0

@ A-letubby Şimdi düzenleme ile çalışıyor - -Pargüman eklendi.
villapx

6

Sekmeyi sizin için eklemek için yankı kullanma grep "$(echo -e \\t)"


6

Bunu ele almanın temel olarak iki yolu vardır:

  1. ( Önerilen ) grep (1) tarafından desteklenen normal ifade sözdizimini kullanın. Modern grep (1), POSIX 1003.2 normal ifade sözdiziminin iki biçimini destekler: temel (eski) RE'ler ve modern RE'ler. Sözdizimi, sırasıyla BSD ve Linux sistemlerinin bir parçası olan re_format (7) ve regex (7) man sayfalarında ayrıntılı olarak açıklanmaktadır. GNU grep (1), pcre (3) kitaplığı tarafından sağlanan Perl uyumlu RE'leri de destekler.

    Normal ifade dilinde sekme sembolü genellikle \tatom tarafından kodlanır . BSD tarafından desteklenen atomu normal ifadeleri uzatılmış ( egrep, grep -EBSD uyumlu bir sistem ile ilgili), hem de Perl uyumlu RE ( pcregrepGNU grep -P).

    Hem temel düzenli ifadeler hem de Linux genişletilmiş RE'lerin görünüşte hiçbir desteği yoktur \t. Hangi regex dilini desteklediğini öğrenmek için UNIX yardımcı program kılavuz sayfasına bakınız (dolayısıyla sed (1), awk (1) ve pcregrep (1) normal ifadeleri arasındaki fark).

    Bu nedenle, Linux'ta:

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

    BSD sisteminde:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Sekme karakterini desene geçirin. Bir komut dosyasını düzenlerken bu basittir:

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

    Bununla birlikte, etkileşimli bir kabukta çalışırken, satıra uygun sembolü yazmak için kabuk ve terminal yeteneklerine güvenmeniz gerekebilir. Çoğu terminalde bu, terminale bir sonraki giriş karakterini kelimenin tam anlamıyla tedavi etmesini söyleyen Ctrl+ Vtuş kombinasyonu ile yapılabilir ( V"verbatim" içindir):

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

    Bazı mermiler komut dizgisi için gelişmiş destek sunabilir. Böyle, bash (1) 'de formun sözcükleri $'string'özel olarak ele alınır:

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

    Bununla birlikte, komut satırında iyi olurken, komut dosyasının başka bir platforma taşınacağı zaman uyumluluk sorunlarına neden olabileceğini lütfen unutmayın. Ayrıca, özel ürünleri kullanırken tırnaklara dikkat edin, lütfen ayrıntılar için bash (1) 'e danışın.

    Bourne kabuğu için (ve sadece değil), aynı davranış düzgün regex oluşturmak için printf (1) tarafından artırılan komut ikamesi kullanılarak taklit edilebilir:

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

4

grep "$(printf '\t')" Mac OS X'te benim için çalıştı


2

gawk kullanın, alan sınırlayıcıyı sekme (\ t) olarak ayarlayın ve alan sayısını kontrol edin. 1'den fazla ise, sekmeler vardır / vardır

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

2
Bu biraz abartılı ve soruyu özlüyor. awk /\t/op sorusu için yeterlidir.
Sınırlı Kefaret

2

İyi bir seçim 'sed olarak grep' kullanmaktır (bu klasik sed eğitiminde açıklandığı gibi ).

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

Örnekler (bash, sh, ksh, csh, .. biçiminde çalışır):

[~]$ 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 yol, ksh, tire vb.

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

Bu benim için Ubuntu Trusty'de (Bash 4.3.11) işe yaramadı, ancak aşağıdakiler işe grep "$(printf '\t')" testfile.txt
yaradı

0

Cevap daha basit. Grep'inizi yazın ve tırnak içine sekme anahtarını yazın, en azından ksh olarak iyi çalışır

grep "  " *

3
önce kabuğuna bir TAB karakteri
girmeyi başarmalısın


0

'G-as-grep' yöntemini kullanmak, ancak sekmeleri kişisel tercihlerin görünür bir karakteriyle değiştirmek, hem hangi dosyaların istenen bilgileri içerdiğini hem de satırlara nerede yerleştirildiğini açıkça gösterdiğinden, en sevdiğim yöntemdir:

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

Satır / dosya bilgilerini veya diğer grep seçeneklerini kullanmak, ancak sekme karakterinin görünür değiştirmesini görmek istiyorsanız, bunu

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

Örnek olarak:

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

DÜZENLEME: Açıkçası yukarıdaki sadece sekmeleri bulmak için dosya içeriğini görüntülemek için yararlıdır --- amaç sekmeleri daha büyük bir komut dosyası oturumunun bir parçası olarak ele almak ise, bu herhangi bir yararlı amaca hizmet etmez.


0

Bu AIX için iyi çalışıyor. İçeren satırları arıyorumJOINED<\t>ACTIVE

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

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

0

Kullanmak isteyebilirsiniz grep "$(echo -e '\t')"

Tek gereklilik echoters eğik çizgi kaçışlarını yorumlayabilmektir.


0

Bu alternatif ikili tanımlama yöntemleri tamamen işlevseldir. Ve tekli ikili karakterlerle sözdizimi kullanımını tam olarak hatırlayamadığım için, awk kullanmasını gerçekten seviyorum. Bununla birlikte, bir kabuk değişkenine POSIX taşınabilir bir şekilde bir değer atamak (örn. TAB = echo "@" | tr "\100" "\011") ve daha sonra onu her yerden, POSIX taşınabilir bir şekilde kullanmak mümkün olmalıdır; de (yani grep "$ TAB" dosya adı). Bu çözüm SEKME ile iyi çalışır, ancak ödevde istenen başka bir ikili değer kullanıldığında (TAB karakterinin değeri 'tr' yerine) diğer ikili karakterleri de iyi çalışacaktır.


0

Diğer cevaplarda verilen $ '\ t' notasyonu kabuğa özgüdür - bash ve zsh'de çalışıyor gibi görünür ancak evrensel değildir.

NOT: Aşağıdaki fishkabuk içindir ve bash'da çalışmaz :

Olarak fishkabuk, bir bir tırnaksız kullanabilir \t, örneğin:

grep \t foo.txt

Veya onaltılık veya unicode gösterimleri kullanabilirsiniz:

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

(bu gösterimler daha ezoterik karakterler için yararlıdır)

Bu değerlerin tırnak içine alınmaması gerektiğinden, alıntılanmış ve alıntılanmamış değerler birleştirilerek birleştirilebilir:

grep "foo"\t"bar"

-4

Yazabilirsin

grep \ t foo

veya

grep '\ t' foo

foo dosyasındaki sekme karakterini aramak için. Muhtemelen başka kaçış kodları da yapabilirsiniz, ancak sadece test ettim \ n. Oldukça zaman alıcı ve neden istediğinizi açık olmasa da, zsh'de sekme karakterini de yazabilirsiniz, başa dönüp sekmeyi tırnak işaretleri içine alabilirsiniz.


-6

Boş alanları birçok kez arayın [[: space:]] *

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

Bunun gibi bir şey bulacaksınız:

'sekme' ..

Bunlar tek tırnak ('), çift değil (").
Grep'te birleştirme işlemini böyle yaparsınız. = -)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.