ファイルから(ファイルから取得された)文字列を検索し、最初に表示される文字列の一部である他の文字列のインスタンスを置き換えます。

ファイルから(ファイルから取得された)文字列を検索し、最初に表示される文字列の一部である他の文字列のインスタンスを置き換えます。

ライナーは名前:0602を検索し、次の名前に達するまでType###のすべてのインスタンスをタイプ700に置き換えます。

sed '/Name: R0602/,/Name.*$/ s/type .*;/type 700;/' file2

このパッドに似たものを使用したいのですが、file1の名前リストを使用してfile2を検索したいと思います。 file1型の文字列を見つけたら、名前部分の終わりに達するまでstring2のすべてのインスタンスを置き換えてから、file1の次の行に対して同じことを行います。

ファイル1

Name: 0602
Name: 0603
Name: 0604

ファイル2:

# Name: R0601
   Container 4 {
  row 12 type 2 {
     set 1 10 {
         name "C4";
         type 300;
     }
     set 11 20 {
         name "C5";
         type 100;
     }
  set 21 20 {
         name "C6";
         type 300;
     }
  set 31 40 {
         name "C7";
         type 200;
     }
      set 31 40 {
         name "C7";
         type 1200;
     }
  }
}

 # Name: R0602
   Container 5 {
  row 12 type 2 {
     set 1 10 {
         name "C4";
         type 300;
     }
     set 11 20 {
         name "C5";
         type 100;
     }
  set 21 20 {
         name "C6";
         type 300;
     }
  set 31 40 {
         name "C7";
         type 300;
     }
      set 31 40 {
         name "C7";
         type 1100;
     }
  }
}


 # Name: R0603
   Container 6 {
  row 12 type 2 {
     set 1 10 {
         name "C4";
         type 200;
     }
     set 11 20 {
         name "C5";
         type 100;
     }
  set 21 20 {
         name "C6";
         type 300;
     }
  set 31 40 {
        name "C7";
        type 500;
     }
      set 31 40 {
        name "C7";
        type 1100;
     }
  }
}
 # Name: R0604
   Container 6 {
  row 12 type 2 {
     set 1 10 {
         name "C4";
         type 200;
     }
     set 11 20 {
         name "C5";
         type 100;
     }
  set 21 20 {
         name "C6";
         type 300;
     }
  set 31 40 {
        name "C7";
        type 500;
     }
      set 31 40 {
        name "C7";
        type 1100;
     }
  }
}
 # Name: R0605
   Container 6 {
  row 12 type 2 {
     set 1 10 {
         name "C4";
         type 200;
     }
     set 11 20 {
         name "C5";
         type 100;
     }
  set 21 20 {
         name "C6";
         type 300;
     }
  set 31 40 {
        name "C7";
        type 500;
     }
      set 31 40 {
        name "C7";
        type 1100;
     }
  }
}

ベストアンサー1

短い awk スクリプト

awk '
  NR == FNR               { names["R"$2]; next }
  $2 == "Name:"           { replace = ($3 in names) }
  $1 == "type" && replace { sub(/type .*/, "type 700;") }
  1
' file1 file2

NR と FNR は awk 組み込み変数です。 NRはこれまでに見た行の総数を計算します。 FNRは、現在のファイルからこれまでに見た行数です。NR == FNR「最初のデータファイルで作業しています」を意味するawk慣用語です。現在のレコード数が合計レコード数と等しい唯一のファイルです。

したがって、最初のファイルを読み取るときは、2番目の列に「キー」を保存しようとします。in後で使用する演算子を考えると、それを「名前」の連想配列のキーとして保存するのが便利な場所です。 2番目のファイルに対応する文字があるので、キーに文字「R」を追加しました。

その当時、$2 == "Name:"私たちはある区域の上にいました。行の3番目の単語が最初のファイルに表示されたら、型の値を変更しようとします。 3番目の単語が連想配列のキーとして($3 in names)表示されることを確認してください。names存在する場合は、最初の単語が「type」の後続の行で置換を実行します。

スクリプトの最後の行が面白いです。1awkに現在の行を印刷するように指示する別の慣用的な略語です。 awkプログラムはcondition {action}一連のペアです。条件が満たされると、所与のタスクが実行される。条件を省略することができ、この場合、各行ごとに演算が実行されます。アクションブロックなしで条件を指定できます。この場合、デフォルトのアクションは現在の行を印刷することです。 awk は空の文字列と 0 を false として扱うので、1条件は常に true です。もっと冗長に感じたら、もっと明確にするの{print}ではなく書き留めます。1

おすすめ記事