grep
Unixプラットフォームのファイルでタブ(\ t)を使用するにはどうすればよいですか?
grep
Unixプラットフォームのファイルでタブ(\ t)を使用するにはどうすればよいですか?
回答:
GNU grepを使用している場合は、Perlスタイルの正規表現を使用できます。
grep -P '\t' *
-P
オプションについて何も知らない。
トリックは、単一引用符の前に$記号を使用することです。また、カットやその他のツールでも機能します。
grep $'\t' sample.txt
zsh
私の知る限り、同様。その$
記号の意味論についてコメントしていただけますか?
$'\t'' '
。これがsh(Androidにデフォルトでインストールされていないbashだけでなく)でも機能することを示す実際の例は、ですbusybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
。
'\ t'メタ文字をgrepで機能させることができませんでした。ただし、2つの代替ソリューションが見つかりました。
<Ctrl-V> <TAB>
(Ctrl-Vを押してからタブを入力)foo | awk '/\t/'
| awk '/\t/'
ソリューションは、すべてのシェル、プラットフォーム、システムで機能します。
awk
ここでうまく機能しますが、非常に大きなファイルを使用する私のマシンでのいくつかのテストでは、を使用するよりも約30%遅くなりますgrep -P
。これは、ユースケースに基づいて簡単で無関係である可能性があり、awk
単に読みやすさと移植性の点で優れている場合があります。
Ask Ubuntuのこの回答から:
Perlで定義された正規表現を使用するようにgrepに指示します(Perlは
\t
タブとして持って います)。grep -P "\t" <file name>
リテラルタブ文字を使用します。
grep "^V<tab>" <filename>
printf
タブ文字を印刷するために使用します。grep "$(printf '\t')" <filename>
1つの方法は(これはBashで)
grep -P '\t'
-P
\ tが機能するようにPerl正規表現をオンにします。
ユーザーunwindが言うように、これはGNU grepに固有の場合があります。別の方法は、シェル、エディター、またはターミナルで許可されている場合は、文字通りタブを挿入することです。
文字通り式の中にタブを挿入するもう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`
これはまさにあなたが探しているものではありませんが、あなたのケースではうまくいくかもしれません
grep '[[:blank:]]'
に相当
grep -P '[ \t]'
したがって、スペースとタブが見つかります。
注、それは私のman grep
で宣伝されていませんが、まだ動作します
$ man grep | grep空白| トイレ 0 0 0
-P
引数が追加されました。
これに対処するには、基本的に2つの方法があります。
(推奨)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拡張正規表現(egrep
、grep -E
BSD互換システムでは)、および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 ...
タブ文字をパターンに渡します。スクリプトファイルを編集する場合、これは簡単です。
# 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 ...
gawkを使用して、フィールド区切り文字をタブ(\ t)に設定し、フィールド数を確認します。1を超える場合は、タブがあります。
awk -F"\t" 'NF>1' file
awk /\t/
opの質問には十分です。
(この古典的な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の方法、ksh、ダッシュなどで機能します:printfを使用してTABを挿入します
grep "$(printf 'BEGIN\tEND')" testfile.txt
grep "$(printf '\t')" testfile.txt
「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
編集:上記は明らかにファイルの内容を表示してタブを見つける場合にのみ役立ちます---目的が大きなスクリプトセッションの一部としてタブを処理することである場合、これは有用な目的を果たしません。
あなたが使いたいかもしれません grep "$(echo -e '\t')"
唯一の要件はecho
、バックスラッシュエスケープの解釈が可能であることです。
これらの代替バイナリ識別方法は完全に機能します。そして、私はawkを使用している人が本当に好きです。単一のバイナリ文字を使用した構文的な使用法を思い出せなかったからです。ただし、シェル変数にPOSIX移植可能な方法(TAB =などecho "@" | tr "\100" "\011"
)で値を割り当て、そこからPOSIX移植可能な方法でそれを使用することも可能です。同様に(つまり、grep "$ TAB"ファイル名)。このソリューションはTABでうまく機能しますが、割り当てで別の目的のバイナリ値が使用されている場合(TAB文字の値が 'tr'の代わりに)、他のバイナリ文字もうまく機能します。
他の回答で示されている$ '\ t'表記はシェル固有です-bashおよびzshで機能するようですが、普遍的ではありません。
注:以下はfish
シェル用であり、bashでは機能しません。
内fish
殻、一方が引用符で囲まれていないを使用することができ\t
、例えば:
grep \t foo.txt
または、16進数またはユニコード表記を使用できます。例:
grep \X09 foo.txt
grep \U0009 foo.txt
(これらの表記は、より難解なキャラクターに役立ちます)
これらの値は引用符で囲まない必要があるため、引用符で囲まれた値と引用符で囲まれていない値を連結することで組み合わせることができます。
grep "foo"\t"bar"
空白スペースを何度も探します[[:space:]] *
grep [[:space:]] * '。' '。'
次のようなものが見つかります:
'タブ' ..
これらは二重引用符( ')であり、二重引用符( ")ではありません。
これが、grepで連結を行う方法です。=-)
grep "<Ctrl+V><TAB>"
、それが動作(初回場合:タイプがgrep "
し、Ctrl + Vキーコンボを押し、その後、Tabキーを押しキー、その後、入力"
およびEnterキーを押し、ほら!)