sed を使用して、複数回表示される単語をリストの単語に置き換えます。

sed を使用して、複数回表示される単語をリストの単語に置き換えます。

複数回発生する行のリストを含むファイルがあります。

output = filename
output = filename
output = filename
output = filename

filenameまた、次の順序でエントリを置き換えるために使用したいtxtファイルには、ファイル名の時系列リストがあります。

2d_slv_Nx.19800111.SUB.nc
2d_slv_Nx.19800213.SUB.nc
2d_slv_Nx.19800322.SUB.nc
2d_slv_Nx.19800510.SUB.nc

私は次のような出力が欲しい

output = 2d_slv_Nx.19800111.SUB.nc
output = 2d_slv_Nx.19800213.SUB.nc
output = 2d_slv_Nx.19800322.SUB.nc
output = 2d_slv_Nx.19800510.SUB.nc

答え1

   $ cat tmplate.sh 
    output = filename

    output = filename

    output = filename

    output = filename

    $ cat mkrepl.sh 

   while read fname
   do
     sed -i -e "0,/filename/s/filename/$fname/" tmplate.sh
   done < tmplate.sh
   $ 

Bashスクリプト:tmplate.shから行を読み取り、各行を変数として抽出し、fnamebashsed置換を使用して実行します。

使用sed

  • -i インライン編集
  • -e表現:

使用範囲

  • 0を/filename/の行に設定します(行0から始まると、最初の置換後にsedが停止します)。
  • filename次へ交換$fname

答え2

これは簡単に解決できますawk

sedループを使用する場合と比較して、このソリューションは入力ファイルを読み取り、出力ファイルを一度だけ書き込み、1つのプロセスのみを使用します。ファイル名のリストが長いほど高速です。


ファイル名を含むファイルが呼び出され、filenames変更する行を含む入力が呼び出されると仮定すると、input次のようになります。

awk 'NR == FNR {name[i++]=$0;next} /^output = filename$/ { $3 = name[j++]; } 1' filenames input > output

説明する:

この条件は、NR == FNR最初のファイルにのみ適用されます。行の追加処理をスキップし、行name[i++]=$0;を配列に保存します。 (も可能。)namenextname[NR]=$0;next

/^output = filename$/置き換える行と一致し、$3 = name[j++];3番目のフィールドを配列の名前に置き換えます。 0から再計算を開始するjのではなく、新しいインデックスを使用しました。i

1暗黙的なデフォルト動作を含む「常に真」の条件。print

メモ:変更したい行が実際の入力と異なるように見える場合は、スクリプトが機能しない可能性があります。filenamesファイルに置き換える行数より少ないデータが含まれている場合、エラー処理は発生しません。

関連情報