リテラルタブを使用せずにタブをgrepする方法と、なぜ\ tが機能しないのですか?


146

(e)grepを使用してファイル内のタブを検索するときは、litteralタブ(^v + <tab>)を使用します。\t正規表現のタブの代わりとして利用することはできません。たとえばsedでは、この式は非常にうまく機能します。

だから、非同種の代替品を使用する可能性はありますか?<tab>非動作/非解釈の背景は何\tですか?


回答:


206

grepは、POSIXで定義されている正規表現を使用しています。何らかの理由で、POSIXは\tタブとして定義されていません。

いくつかの選択肢があります:

  • grepに、perlで定義された正規表現を使用するように指示します(perlは\tタブとして):

    grep -P "\t" foo.txt

    manページは、これが「実験的」機能であることを警告しています。少なくとも\tうまくいくようです。しかし、より高度なperl正規表現機能はそうではないかもしれません。

  • printfを使用して、タブ文字を印刷します。

    grep "$(printf '\t')" foo.txt
  • リテラルタブ文字を使用します。

    grep "^V<tab>" foo.txt

    つまりgrep "、を入力してからを押しctrl+v、次にを押してtabからを入力し" foo.txtます。ctrl+vターミナルで押すと、次のキーがそのまま使用されます。つまり、端末はタブキーにバインドされた何らかの機能をトリガーする代わりにタブ文字を挿入します。

  • bashのANSI Cクォート機能を使用ます。

    grep $'\t' foo.txt

    これはすべてのシェルで機能するわけではありません。

  • awkを使用します。

    awk '/\t/'
  • sedを使用します。

    sed -n '/\t/p'

POSIXおよびその他のシステムで定義されている文字クラスの概要については、正規表現に関するウィキペディアの記事を参照してください。


:enzotibの答え私は、次を追加してみましょうに基づかgrep $'\t' foo.txt(私は通常、書きますfgrepの代わりにgrep
ウォルターTross

環境変数の値を使用して、これが必要でした。使用しましたgrep "$(printf '\t')${myvar}" foo.txt。うまくいきました。数回試してみたところ、最後のフォームが機能しませんでした。
sancho.s

1
プレーンgrepが黙っ\tてタブとして解釈できない理由はありますか?POSIXはそれが\t何か他のものを意味することを要求しますか?おそらく、リテラルの\ 後にt?が続くだけに一致するはずです。
アーロンマクデイド

おそらく、BSD(OSXを含む)grepには-Pオプションがないことに注意する価値があります。
-TextGeek

マニュアルページからThis is highly experimental and grep -P may warn of unimplemented features.おそらく-Pレガシーシステムで使用するのは良い考えではありません。printf選択が優れている
Avindra Goolcharan

13

それはあなたが聞きたいと思う答えそのものではありませんが、エスケープシーケンスの可能な使用はbashによって提供されます

command | grep $'\t'

(二重引用符で囲まないでください!)。


1
-Eの必要はありません(検索対象は正規表現ではありません)。コマンドからパイプする必要もありません。言うは、bashのこの非常に見落とし機能を指摘するために($が先行シングル引用符で囲まれた文字列)をお願いします
ウォルターTross

2
実際、@ enzotibが答えを単純に編集することをお勧めしますgrep $'\t'
Teemu Leisti

これはbashの機能であり、他のシェル(Ubuntuなどのシェルスクリプトのデフォルトであるダッシュなど)によって実行されると(サイレントに)間違った動作をすることを強調する必要があります
xjcl


1

タブにはASCIIの16進コードを使用することに常に頼ることができます。

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

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