複数回発生する行のリストを含むファイルがあります。
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から行を読み取り、各行を変数として抽出し、fname
bashsed
置換を使用して実行します。
使用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;
を配列に保存します。 (も可能。)name
next
name[NR]=$0;next
/^output = filename$/
置き換える行と一致し、$3 = name[j++];
3番目のフィールドを配列の名前に置き換えます。 0から再計算を開始するj
のではなく、新しいインデックスを使用しました。i
1
暗黙的なデフォルト動作を含む「常に真」の条件。print
メモ:変更したい行が実際の入力と異なるように見える場合は、スクリプトが機能しない可能性があります。filenames
ファイルに置き換える行数より少ないデータが含まれている場合、エラー処理は発生しません。