awk、sed、またはperlを使用して1つの列のみで値を取得する

awk、sed、またはperlを使用して1つの列のみで値を取得する

次のファイルがあります。

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'

John11〜26列の範囲内で開始して終了する必要があります。

特定の列を空白に置き換えることは、grepの機能を超えています。 GNU grepを使用すると、一致する部分のみを出力できますが、間に余分なスペースがある-o2つの列を結合することはできません。

答え3

tab=$(printf '\t')
cut -c12-26 file | paste - file | grep "^[^$tab]*John" | cut -c1-16,60-

Gilesが言ったように、一人ではできませんgrep。 reに一致する行を印刷する(コマンド)をgrep示します。g/re/ped/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

これ破片テストされた内容は次のとおりです。

各ファイルサイズと破片、何度も繰り返し、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

関連情報