次のファイルがあります。
Marketing Ranjit Singh FULLEagles Dean Johnson
Marketing Ken Whillans FULLEagles Karen Thompson
Sales Peter RobertsonPARTGolden TigersRich Gardener
President Sandeep Jain CONTWimps Ken Whillans
Operations John Thompson PARTHawks Cher
Operations Cher CONTVegans Karen Patel
Sales John Jacobs FULLHawks Davinder Singh
Finance Dean Johnson FULLVegans Sandeep Jain
EngineeringKaren Thompson PARTVegans John Thompson
IT Rich Gardener FULLGolden TigersPeter Robertson
IT Karen Patel FULLWimps Ranjit Singh
grepコマンドを使用して2番目の列で「John」を検索し、最後の列を検索したいのですが、2番目の列のすべての「John」に対して最後の列を出力したいです。
最終結果は次のようになります。
John Thompson Cher
John Jacobs Davinder Singh
Dean Johnson Sandeep Jain
答え1
#! /bin/bash
while read line; do
if [[ ${line:11:15} =~ John ]]; then
echo " ${line:11:15} ${line:43}"
fi
done <file
答え2
grep
行の先頭から正しい文字数を一致させることで選択を実行できます。
grep -E '^.{11,22}John'
John
11〜26列の範囲内で開始して終了する必要があります。
特定の列を空白に置き換えることは、grepの機能を超えています。 GNU grepを使用すると、一致する部分のみを出力できますが、間に余分なスペースがある-o
2つの列を結合することはできません。
答え3
tab=$(printf '\t')
cut -c12-26 file | paste - file | grep "^[^$tab]*John" | cut -c1-16,60-
Gilesが言ったように、一人ではできませんgrep
。 reに一致する行を印刷する(コマンド)をgrep
示します。g/re/p
ed/ex/vi
答え4
今表示されたソリューションのいくつかのヒントを組み合わせてみましょう。
Stephen + Gilesから:
grep -E '^.{11,22}John' source.txt | cut -c12-26,44-
# or, if you want only "John " and not Johnson, add a space after John.
grep -E '^.{11,22}John ' source.txt | cut -c12-26,44-
/bin/grep
ここでも and を使用する必要があります/bin/cut
。
Giles + Haukeから:
grep -E '^.{11,22}John' source.txt | while read line; do echo "${line:11:14} ${line:43}"; done
/bin/grep
ここでも and を使用する必要がありますecho
。現代のシェルでは、echo
次のものを見つけることができます組み込みコマンドしたがって、それほど必要ではありません。
Haukeのソリューションは、インストーラの面でより安価です。質問で必要に応じてecho
(組み込みbash
)のみが必要ですが、それでも必要ありません。/bin/grep
修正するしばらく遊ぼう
日常生活で私たちは走っています破片インスタントで生成され、再度使用されない可能性があるコードは、支出が必ずしも便利ではありません。私たちの人間の年齢最適化するか、別のバリエーションを試してみてください...しかし「Crazy Years」のセメル:一方でこれがcase-study question
、たぶんでも宿題わかりません。 IMHO、この光学系では、さまざまな方法とソリューションの両方が便利です。
多数の行については、一連のシェルコマンドよりもコンパイルされたプログラムを使用する方が良い(速い)ことにすべて同意できるようです。ところで何が大きいのですか?私は数字(およびグラフ)が単語よりもアイデアをよりよく表現していると思います。見てみましょう。
ここレシピ:行数が増加するファイルセット、窒素、準備しなさい。ここに掲載された原文の11行のうち、各行をランダムに抽出しました。
価値窒素使用されるのはです
11 22 55 110 220 550 1100 2200 5500 11000 110000 1100000 11000000
。
これ破片テストされた内容は次のとおりです。
Cut+Paste+Grep+Cut
tab=$(printf '\t') ; cut -c12-26 file | paste - file | grep "^[^$tab]*John" | cut -c1-16,60-
これ-グリーンOnly Grep
- 青grep -E '^.{11,22}John' source.txt
。grep
必要に応じて出力形式を指定しません。- この
Grep+Cut
赤[grep -E '^.{11,22}John' source.txt | cut -c12-26,44-
]。 - - 紫
Grep+While
[上記の答え、grepとwhileループを参照]。 While loop
- 黄色不要な完全なbashソリューションgrep
各ファイルサイズと破片、何度も繰り返し、NRは略語、400から始まり(短いファイルの場合)窒素最後のものは100、10、1に減ります。
その値は次のように記録されます。1行あたりの時間、銃士、また〜として知られるリアルタイム組み込み機能による測定time
と平均化NRは略語そして窒素。両方とも銃士そして窒素10の累乗にわたって商用ログ(デフォルト10または10の累乗)をプロットします。報告された線は、各点に接触するベジェ曲線です。
より大きい値の場合窒素これ1行あたりの時間ほぼ一定になります。これを漸近的行動といいます。期待どおりにコンパイルされたプログラムで使用される数値が小さいほど、結果が速くなります。
逆に、小さなファイルの場合、結果は逆です。さまざまなコードの効率は(たとえば)40行と140行の間で交差します。小さなファイルなので本当に小さい容量ですが、全体的に人間の時間使用すると、多数の小さなファイルを処理する必要がある場合、同じ考慮事項は維持されなくなります。純粋なbashコード(黄色)は緑色のコードよりも漸近的に8.12倍遅く157倍遅くても赤いファイルの場合(11Mラインファイルの場合は緑色の場合は41.21秒、赤色の場合は2.16秒ではなく334.56秒を使用)、400回の繰り返し時間に1.20秒を使用した場合、11Mラインファイルの場合はそれぞれ2.16倍と1.58倍高速です。赤の場合は1.89秒、緑の場合は2.59秒ではありません。
結論として: たくさん知るほど挑戦できる、そして可能であることを確認してください! :-)
Ps > 同様の考慮事項は以下でも見つけることができます。ユーザー時間そしてシステム時間しかし、交差領域が若干異なります。
強く打つ 4.3.11(1)-リリース
生地(GNUコアユーティリティ)8.21
切る (GNUコアユーティリティ)8.21
grep (GNU grep) 2.16
コア3.13.0-24 - 一般 x86_64