3

各レコードの特定の 2 番目のフィールド (正規表現に一致する) を出力したい

awk '$2 ~ /regex1/'

ただし、regex2 と regex3 の間にある特定のレコードのみ

awk '/regex2/,/regex3/'

regex2 と regex3 の間にないその他のレコードは、通常どおりに出力されます (すべてのフィールド)。

アイデアはありますか?

入力と出力の簡単なサンプル:

入力

parrot   milana  3 ukraine
dog      husky   1 poland
cat      husky   5 france
elephant malamut 5 belgium
bird     husky   5 turkey

出力: (見せて

parrot   milana  3 ukraine
dog      husky   1 poland
         husky            
elephant malamut 5 belgium    
bird     husky   5 turkey
  1. 入力全体を表示しますが:
  2. /dog/ と /elephant/ の間 (これらのレコードを変更せずに表示) は、正規表現 /husky/ に一致する 2 番目のフィールドのみを表示します

これが役に立つことを願っています...

4

3 に答える 3

5

これ:

awk '/regex2/,/regex3/'

の省略形です

awk '/regex2/{f=1} f; /regex3/{f=0}'

短縮版のIMHOは、その簡潔さは、開始行を印刷しない、終了行を印刷しない、および/または他のREを導入するなど、他の基準で構築しようとするときに導入する難しさに値しないため、絶対に使用しないでください。あなたが今しているように範囲内で一致するように。

それを考えると、あなたはこのスクリプトから始めています:

awk '/dog/{f=1} f; /elephant/{f=0}'

そして、「ハスキー」を見つけた行だけを印刷したいので、それは単純で明白な微調整です。

awk '/dog/{f=1} f && /husky/; /elephant/{f=0}'

編集:変更された要件に応じて、タブ区切りファイルを使用:

$ cat file
parrot  milana  3       ukraine
dog     husky   1       poland
cat     husky   5       france
elephant        malamut 5       belgium
bird    husky   5       turkey

$ awk '
BEGIN{ FS=OFS="\t" }
/elephant/ {f=0}
{
   if (f) {
      if ($2 == "husky") {
         print "", $2
      }
   }
   else {
      print
   }
}
/dog/      {f=1}
' file
parrot  milana  3       ukraine
dog     husky   1       poland
        husky
elephant        malamut 5       belgium
bird    husky   5       turkey

もっと簡単に書くことができます:

$ awk '
BEGIN{ FS=OFS="\t" }
/elephant/ {f=0}
f && /husky/ { print "", $2 }
!f
/dog/      {f=1}
' file
parrot  milana  3       ukraine
dog     husky   1       poland
        husky
elephant        malamut 5       belgium
bird    husky   5       turkey

しかし、if-else構文は、初心者がawkを実行するために最も明確で、変更するのが最も簡単だと思います。別の出力フォーマットが必要な場合は、マニュアルで「printf」を検索してください。

于 2012-12-13T17:57:23.307 に答える
1

infile:

$ cat input

parrot   milana  3 ukraine
dog      husky   1 poland
cat      husky   5 france
elephant malamut 5 belgium
bird     husky   5 turkey

指図:

$ awk '/dog/{m=1} $2 ~ /husky/ && m{print $2} !m{print} /elephant/{m=0}' input

parrot   milana  3 ukraine
husky
husky
bird     husky   5 turkey
于 2012-12-13T19:08:06.840 に答える
0

あなたの質問にはいくつかのあいまいさがありますが、これでうまくいくはずです:

awk '/regex2/ {inside=1}
     /regex3/ {inside=0}
     $2 ~ /regex1/ && inside {print $2}
     !inside {print}' input_file
于 2012-12-13T17:09:44.750 に答える