UNIXでタブをgrepする


418

grepUnixプラットフォームのファイルでタブ(\ t)を使用するにはどうすればよいですか?


53
ただ、使用grep "<Ctrl+V><TAB>"、それが動作(初回場合:タイプがgrep "し、Ctrl + Vキーコンボを押し、その後、Tabキーを押しキー、その後、入力"およびEnterキーを押し、ほら!)
ルーク

16
ctrl + vは本当に悪いアイデアです!...はい、コンソールコマンドからは機能するかもしれませんが、スクリプトに入力しても機能しない可能性があります(たとえば、エディタの
なすがまま


参照:askubuntu.com/questions/53071/...(だけでなく下のリンク)
シリ・

回答:


375

GNU grepを使用している場合は、Perlスタイルの正規表現を使用できます。

grep -P '\t' *

それは私のパターンに対して機能しないようです。その構文を使用しようとしても何も出力されません。(Mac OS Xのバリアントは異なりますか?)
futureelite7

2
@futureelite:Appleのドキュメント(developer.apple.com/Mac/library/documentation/Darwin/Reference/…)によると、Mac OS X grepプログラムは-Pオプションをサポートする必要があります。superuser.comで新しい質問を作成することを検討してください。
2010

3
それはGNU UNIXにとって非常に良いことですが、POSIX Solaris、AIX、およびHP-UXについてはどうでしょうか。それらは-Pオプションについて何も知らない。
2013

21
@rook GNUはUNIXではありません。
リリーチョン

5
Mac OSXでは、-eを使用してパターンを指定できます
Faisal Feroz

314

トリックは、単一引用符の前に$記号を使用することです。また、カットやその他のツールでも機能します。

grep $'\t' sample.txt

7
救世主のヒントは命を救います!それはで仕事をしてzsh私の知る限り、同様。その$記号の意味論についてコメントしていただけますか?
Romain

2
文字列に '\ t'以外が含まれている場合は機能しません。たとえば、 "\ t"(タブ+スペース)をどのように検索しますか?
ラマン

6
ラマン:を使用できます$'\t'' '。これがsh(Androidにデフォルトでインストールされていないbashだけでなく)でも機能することを示す実際の例は、ですbusybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
v6ak 2013

5
$ '...'はbashのイディオムだと思います。おそらくshでは動作しません。Dunno、cshまたはtcshについて。
Edward Falk

5
'man bash'から:$ 'string'形式の単語は特別に扱われます。単語は文字列に展開され、バックスラッシュでエスケープされた文字はANSI C規格の指定に従って置き換えられます。バックスラッシュエスケープシーケンスが存在する場合、デコードされます...
broeni

84

'\ t'メタ文字をgrepで機能させることができませんでした。ただし、2つの代替ソリューションが見つかりました。

  1. 使用<Ctrl-V> <TAB>(Ctrl-Vを押してからタブを入力)
  2. awkの使用: foo | awk '/\t/'

4
この| awk '/\t/'ソリューションは、すべてのシェル、プラットフォーム、システムで機能します。
Samveen

6
+1はポータブルPOSIXソリューションで、bashisms、zshism、GNUism、linuxismsを使用しません。
Jens 2013

1
ctrl-Vは、(ノートやスクリプトから)コピーして貼り付けたい場合には役に立ちません。目に見える '\ t'を持つ明示的なソリューションを使用すると、リテラルTAB(つまり、空白のように見えるもの)がコピー貼り付け時にSPCに変換されることがよくあります...
plijnzaad

awkここでうまく機能しますが、非常に大きなファイルを使用する私のマシンでのいくつかのテストでは、を使用するよりも約30%遅くなりますgrep -P。これは、ユースケースに基づいて簡単で無関係である可能性があり、awk単に読みやすさと移植性の点で優れている場合があります。
theferrit32

43

Ask Ubuntuのこの回答から:

Perlで定義された正規表現を使用するようにgrepに指示します(Perlは\tタブとして持って います)。

grep -P "\t" <file name>

リテラルタブ文字を使用します。

grep "^V<tab>" <filename>

printfタブ文字を印刷するために使用します。

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


ctrl-Vは、(ノートやスクリプトから)コピーして貼り付けたい場合には役に立ちません。目に見える '\ t'を持つ明示的なソリューションを使用すると、リテラルTAB(つまり、空白のように見えるもの)がコピーペースト時にSPCに変換されることがよくあります
plijnzaad

31

1つの方法は(これはBashで)

grep -P '\t'

-P \ tが機能するようにPerl正規表現をオンにします。

ユーザーunwindが言うように、これはGNU grepに固有の場合があります。別の方法は、シェル、エディター、またはターミナルで許可されている場合は、文字通りタブを挿入することです。


kshシェルの不明なPオプション
Sachin Chourasiya 2009

unwindが言うように、GNU grepに固有の場合があります。ただ明確にした。
tjmoore

どのようにタブを追加しますか?タブボタンを押してもオートコンプリートは開始されませんか?(これはbashスクリプトでは機能するが、コマンドラインでは機能しない可能性があります)
AntonioCS

1
上記のSamKriegによる@AntonioCSでは、シェルで任意の文字を入力できるようにするために、最初にCTRL-vを入力します。askubuntu.com/questions/53071/…
Denis Arnaud

2
-Pはシェルではなく、grepに固有です。-Pは、GNU grepがインストールされていれば、どのシェルでも動作するはずです
plijnzaad 2017年

13

文字通り式の中にタブを挿入するもう1つの方法は$'\t'、Bashであまり知られていない引用を使用することです。

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

(固定文字列を照合する場合は、これを '-F'モードで使用できることに注意してください。)

変数を使用すると、表記が読みやすくなり、扱いやすくなります。

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

10

これはまさにあなたが探しているものではありませんが、あなたのケースではうまくいくかもしれません

grep '[[:blank:]]'

に相当

grep -P '[ \t]'

したがって、スペースとタブが見つかります。

§文字クラス

注、それは私のman grepで宣伝されていませんが、まだ動作します

$ man grep | grep空白| トイレ
      0 0 0

@ A-letubby編集で機能するようになりました- -P引数が追加されました。
villapx 2016


6

これに対処するには、基本的に2つの方法があります。

  1. 推奨)grep(1)でサポートされている正規表現構文を使用します。最新のgrep(1)は、基本的な(廃止された)REと最新の REの2つの形式のPOSIX 1003.2正規表現構文をサポートしています。構文は、それぞれBSDおよびLinuxシステムの一部であるre_format(7)およびregex(7)のマニュアルページで詳細に説明されています。GNU grep(1)は、pcre(3)ライブラリによって提供されるPerl互換のREもサポートしています。

    正規表現言語では、タブ記号は通常\tアトムによってエンコードされます。アトムは、BSD拡張正規表現(egrepgrep -EBSD互換システムでは)、およびPerl互換RE(pcregrep、GNU grep -P)でサポートされています。

    基本的な正規表現とLinux拡張REのどちらも、 \t。UNIXユーティリティのマニュアルページを参照して、サポートされている正規表現言語を確認してください(したがって、sed(1)、awk(1)、およびpcregrep(1)の正規表現の違い)。

    したがって、Linuxでは:

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

    BSD同様のシステム:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. タブ文字をパターンに渡します。スクリプトファイルを編集する場合、これは簡単です。

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

    ただし、対話型シェルで作業するときは、シェルとターミナルの機能に依存して、適切な記号を行に入力する必要がある場合があります。ほとんどの端末では、これはCtrl+ Vキーの組み合わせを介して行うことができ、次の入力文字を文字どおりに処理するように端末に指示します(これVは「逐語的」用です)。

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

    一部のシェルは、コマンドの組版に対して高度なサポートを提供します。そのため、bash(1)では、次の形式の単語は$'string'特別に扱われます。

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

    ただし、コマンドラインで快適に使用できるため、スクリプトを別のプラットフォームに移動するときに互換性の問題が発生する可能性があります。また、スペシャルを使用するときは引用符に注意してください。詳細については、bash(1)を参照してください。

    Bourneシェル(およびそれだけではない)の場合、printf(1)によって拡張されたコマンド置換を使用して同じ動作をエミュレートし、適切な正規表現を構築できます。

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


2

gawkを使用して、フィールド区切り文字をタブ(\ t)に設定し、フィールド数を確認します。1を超える場合は、タブがあります。

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

2
これは少しやり過ぎで、質問を逃します。awk /\t/opの質問には十分です。
限定的な贖罪

2

(この古典的なsedチュートリアルで説明されているように)「sed as grep」を使用することをお勧めします。

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

例(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の方法、ksh、ダッシュなどで機能します:printfを使用してTABを挿入します

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

これは、Ubuntuのトラスティ(4.3.11バッシュ)の上に私のために動作しませんでした、次のように仕事をしたものの:grep "$(printf '\t')" testfile.txt
ジョシュRumbut

0

答えは簡単です。あなたのgrepを書いて、引用符の中にタブキーを入力してください、それは少なくともkshでうまく機能します

grep "  " *

3
最初に、シェルにTAB文字を入力する必要があります-ほとんどのシェルはこのキーをコマンドとして解釈します(完了)
Kaii


0

「sed-as-grep」メソッドを使用しますが、タブを個人的な好みの表示文字に置き換えることが私のお気に入りの方法です。これは、要求された情報を含むファイルと、行内のどこに配置されるかを明確に示すためです。

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

行/ファイル情報、または他のgrepオプションを利用したいが、タブ文字の目に見える置換を表示したい場合は、次のようにしてこれを実現できます。

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

例として:

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

編集:上記は明らかにファイルの内容を表示してタブを見つける場合にのみ役立ちます---目的が大きなスクリプトセッションの一部としてタブを処理することである場合、これは有用な目的を果たしません。


0

これは、AIXでうまく機能します。を含む行を検索していますJOINED<\t>ACTIVE

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

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

0

あなたが使いたいかもしれません grep "$(echo -e '\t')"

唯一の要件はecho、バックスラッシュエスケープの解釈が可能であることです。


0

これらの代替バイナリ識別方法は完全に機能します。そして、私はawkを使用している人が本当に好きです。単一のバイナリ文字を使用した構文的な使用法を思い出せなかったからです。ただし、シェル変数にPOSIX移植可能な方法(TAB =などecho "@" | tr "\100" "\011")で値を割り当て、そこからPOSIX移植可能な方法でそれを使用することも可能です。同様に(つまり、grep "$ TAB"ファイル名)。このソリューションはTABでうまく機能しますが、割り当てで別の目的のバイナリ値が使用されている場合(TAB文字の値が 'tr'の代わりに)、他のバイナリ文字もうまく機能します。


0

他の回答で示されている$ '\ t'表記はシェル固有です-bashおよびzshで機能するようですが、普遍的ではありません。

注:以下はfishシェル用であり、bashでは機能しません

fish殻、一方が引用符で囲まれていないを使用することができ\t、例えば:

grep \t foo.txt

または、16進数またはユニコード表記を使用できます。例:

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

(これらの表記は、より難解なキャラクターに役立ちます)

これらの値は引用符で囲まない必要があるため、引用符で囲まれた値と引用符で囲まれていない値を連結することで組み合わせることができます。

grep "foo"\t"bar"

-4

入力できます

grep \ t foo

または

grep '\ t' foo

ファイルfooでタブ文字を検索します。テストしたのは\ nだけですが、おそらく他のエスケープコードも実行できます。かなり時間がかかり、必要な理由が明確ではありませんが、zshでタブ文字を入力して先頭に戻り、grepしてタブを引用符で囲むこともできます。


-6

空白スペースを何度も探します[[:space:]] *

grep [[:space:]] * '。' '。'

次のようなものが見つかります:

'タブ' ..

これらは二重引用符( ')であり、二重引用符( ")ではありません。
これが、grepで連結を行う方法です。=-)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.