
質問
次の形式の32Mラインファイルがあります
token^Iname^Iurl$
^I
どこに商標エスケープシーケンス$
です。行末。
url
このフィールドに対して10,000個以下の一致項目を取得する必要がありますname
。私がしたことは
# Get second column
cut -f2 <myFile> |
# Find the word and line number
grep -nwi "<matchWord>" |
# Get just the number
cut -f1 -d ':' |
# Not more than 10k
head -n10000
次に、前の出力の各項目について
# Print line number
sed -n '<number>{p;q}' <myFile>
# Get 3rd field
cut -f3
今の最後の仕事はsed
非常に遅いです。grep
最初の1,000ゲームをプレイした後でも、遅くならない方法だけを使用するか、他の方法を使用してこれらすべてを取得する方法を知りたいです。
アイデア
grep
cut -f2
行全体(何もない)から2番目の列に対してのみ実行できる場合は完璧ですcut -f3
。しかし、どうすればいいのかわかりません。
はい
ラインxyz
qwertyuiop^Ibananas are yellow^Ihttp://mignons.cool$
単語の一致黄色現場でname
- >くださいhttp://mignons.cool
。
cut
ライブコンテンツtoken
をurl
。
grep
に送信すると、cut
私は興味のあるフィールドmyFile
にアクセスできなくなります。url
入力と予想出力
入力ファイル:
mxp4EdOy-IXkuwsuOfs0EQ^Ilegal yellow pad paper^I0/3/3031.jpg$
AeS7tgmlVffBhousr9YY5Q^Ihelicopter parking only sign^I0/3/3032.jpg$
8dl-VixSjG4Y0FpX9f5KHA^Iwritten list ^I0/3/3033.jpg$
XYvKZC3D_JSwlY8SPl-zLQ^Ihelicopter parking only road sign^I0/3/3034.jpg$
xF6zpvpHcmfpHP2MmT2FVg^Irun menu windows programming^I0/3/3035.jpg$
mCJvV2rXOmItLBkMZlyIwQ^Icoffee mug^I0/3/3040.jpg$
ZiobHk_dLsN-Q921KPJUTA^Icarpet^I0/3/3197.jpg$
xFrbGOMfVMl0WeqVAcT27A^Iwater jugs^I0/3/3199.jpg$
^I
どこに商標エスケープシーケンス$
です。行末。
単語を一致させますhelicopter
。
予想出力(10,000行以下):
0/3/3032.jpg
0/3/3034.jpg
潜在的なソリューション
フィールドにはurl
数字のみが含まれているため、次のことができます。
cut -f 2,3 <myFile> | grep <matchWord> | cut -f2 | head -n10000
grep
しかし、2番フィールドだけに行くのが良いと思います...
答え1
これを行う方法はいくつかあります。最も簡単なのはおそらくawk
$ awk -F$'\t' '$2 = /helicopter/ {print $3}' input.txt | head -n 10000
0/3/3032.jpg
0/3/3034.jpg
-F$'\t'
フィールド区切り記号をTABに設定$2 = /helicopter/
フィールド2でのみ一致print $3
一致する項目にフィールド 3 を印刷します。
大文字と小文字を区別せずに単語全体を一致させるには、次のようにします。
awk -F$'\t' 'tolower($2) ~ /\<helicopter\>/ { print $3}' input.txt | head -n 10000
((単語の境界を表示)のみ機能できます。 Linuxを使用している場合はこれが標準です\<
。また、比較演算子がから変更されました。\>
gawk
=
~
答え2
LC_ALL=C
ご使用の環境でローカルに設定することもできます。
LC_ALL
UTF8ロケールの場合、grepが一致する前に入力ストリームをUTF8にデコードする必要があるため、作業速度が大幅に遅くなる可能性があります。grep
答え3
おそらく切り取ろうとしてはいけませんcut
。実際に、32M入力ラインを処理するためにパイプラインを単一のプロセスにまとめようとすると、タスクの完全な完了時間に悪影響を及ぼす可能性が高くなります。ただし、これはタスクを実行しているコンピュータの種類によって異なります。
データを処理するマシンに複数のプロセッサコアがある場合、通常はワークループを単一のプロセスに統合することは、タスク全体を単一のプロセッサコアに統合することを意味します。これは、プロセッサコアが1つしかないシステム、またはCPU時間全体が重要な場合に理想的です。
つまり、grep
2番目のフィールドのみを使用できます。
grep -E $'\t(.* )?yellow( .*)?\t' <infile
...このパターンは、1行の2つのタブ文字の間にある文字列と一致し、両方が空白またはフィールド区切りタブ文字で区切られた文字列とのみ一致します。 GNUでは、ax matchスイッチをgrep
追加して-m
出力を10K以下に制限することもできます。だから...
grep -m10000 -E $'\t(.* )?yellow( .*)?\t' <infile | cut -f3
...全体の作業を完了するのに十分です。