File1でsed置換を実行してFile2行の出力を変更する方法

File1でsed置換を実行してFile2行の出力を変更する方法

File1.txtにはホストのリストが含まれています。

computer_1
computer_2

File2.txtにはコマンドのリストが含まれています。

ping host_name -c 10
dig host_name A host_name AAAA +short 

...ホストで実行されます。コマンドを実行する前に、file2の文字列をFile1の物理ホスト名sed -e "s/host_name/$line/" $2に置き換えてください。host_name私は最終的に:

ping computer_1 -c 10
dig computer_1 A computer_1 AAAA +short 
ping computer_2 -c 10
dig computer_2 A computer_2 AAAA +short 

この出力をコマンドとして実行するにはどうすればよいですか?

私は以下を含む成功しなかったいくつかの初心者アプローチを試しました。

while read line; do
    commands="$(sed -e "s/host_name/$line/" $2)"
    eval $commands
done < $1

答え1

私はそれが期待どおりに機能しない引用符内の引用符の問題であると思います。

コードの構文を強調表示すると、何が起こっているかがヒントになります。s/host_name/$line/ロープの残りの部分は赤ではなく黒であることに注意してください。これは、bashが理解していないいくつかのゴミを含む2つの文字列を生成したためです。

このようなことがうまくいくはずです

while read line; do
    commands=$(sed -e "s/host_name/$line/" $2)
    eval "$commands"
done < $1

答え2

while read loopaとaの両方を持つことができます。for loop

A.しかし別名foor loopが必要です。mapfilereadarray

mapfile -t commands < file2.txt
mapfile -t hosts < file1.txt

for h in "${hosts[@]}"; do
  for c in "${commands[@]}"; do
    echo  command "$c" "$h"
  done
done

bashが十分に新しくない場合、一般的な回避策は次のとおりです。mapfile

IFS=$'\n' read -rd '' -a array < file.txt

または

while IFS=  read -r file; do
  array+=("$file")
done < file.txt

次に、"${array[@]}"すべての値/要素を保存します。


サイクルwhile read

while IFS= read -ru "$fd" h; do
  while IFS= read -r c; do
    echo command "$c" "$h"
  done < file2.txt
done {fd}< file1.txt
  • echo出力が正しいと思われる場合は、それを削除して実際にコマンドを実行してください。
  • どちらのファイルも1行に1つのエントリがあると仮定すると、組み込みのものでcommand十分です。つまり、1行に複数のコマンドを区別する必要はありません;。他の点ではそうです。eval

  • $fd任意の名前で、任意のファイル記述子を使用します。 bashが十分に新しくない場合は、採用後に{fd}変更することはできません。ループの何かが食事/喫煙の場合は、他のものを使用する必要があります。302fdwhile readstdinssh

関連情報