2017-10-17 22 views
0

私はsedで実行したい置換リストを持っています。置換を単一のsedコマンドに組み合わせる代わりに、私は各置換をbashループの繰り返しで実行したいと思います。たとえば:次の反復へのbashループ反復の出力

cat ${input} | 
for subst in "${substlist}"; do 
    sed 's/'${subst}'/modified_'${subst}'/g' 
done > ${output} 

私は、各反復は、全体の流れを変更しますが、私は最初の反復が入力を取得することを見ていることを期待します。

このパターンはbashでも可能ですか?

+0

がところで、{substlist} '文字列を拡大して' $ - 一般言い換えれば、引用符で囲まれていない展開による単語分割に頼るのではなく、適切な配列を使用する必要があります。つまり、ベストプラクティスは 'substlist =("第1 ""第2 ""第3 ")です。 "$ {substlist [@]}"のsubstのために; do ... ... –

+1

なぜあなたはそれらを1つの 'sed'コマンドに組み合わせたいのですか?それが答えのいくつかです。 – Barmar

+0

ところで、あなたが一度に(つまり、同時に)異なる 'sed'プロセス(すべての奇妙な理由で)ですべての置換を実行したい場合、そのために最も適切な"ループ "の種類は再帰関数です。 'for'ループです。次に例を示します。 'multised(){case $#in 0)cat ;; 1)sed -e "$ 1" ;; *)ローカルcur = $ 1;シフト; sed -e "$ cur" | multised "$ @" ;;エサック; } ' - 配列に' substs'がある場合、 'multised '$ {substs [@]}" <"$input" > "$ output" 'として使用できます。 –

答えて

-1

入力ファイルを出力ファイルにコピーし、-iオプションを使用して置換を実行して、そのファイルを上書きし続けます。する必要があるBSD/OSX sed

cp "$input" "$output" 
for subst in $substlist 
do 
    sed -i "s/$subst/modified_$subst/g" "$output" 
done 

sed -i '' "s/$subst/modified_$subst/g" "$output" 
+0

余分なコピー操作と移植性のヒット(BSDの 'sed'バージョンの' -i'では動作しません)を、どのような目的に使用しますか? –

+0

@CharlesDuffy彼らは1つの 'sed'コマンドでそれをしたくないと言った。 – Barmar

+0

ああ。私は興味を持っています...それが本当の理由であるかどうかを知るためには(XYの問題である - すなわち、ループが引数リストを作るために使われるかもしれないということを知らない)、公正ではありません。 –

0

ここでは、単一のストリームとしてそれを行うための一つの方法です。 ${substlist}からsedの引数を構築し、一度sedの呼び出し:

#!/bin/sh 

cat ${input} | 
sed `for subst in ${substlist}; do 
     echo " -e s/${subst}/modified_${subst}/g " 
    done` > ${output} 

${substlist}にある内容に応じて追加のエスケープ処理を行う必要があります。

+0

OPは引用符で囲まれていない拡張を一度実行しているだけで十分です。それからの出力の引用されていない拡張*をすることは、目的のために失敗事例を増やすことです。 (また、bashの 'echo'がPOSIX仕様に準拠していないため、 '-e'は' sed'にリテラル '-e'引数を渡すのではなく、どのように動作するのかを変更します。置換のうち1つを除いて全てが入力ファイル名として扱われ、 'sed'によって実行される操作ではありません)。 –

+0

優れたポイント。 –

+0

@CharlesDuffy#を示すために編集されました!/ bin/shでも、エコーとの移植性の問題はそれが貧弱な解決策になることに同意します。 –

1

sedに渡す-eオプションの配列を作成します。

filters=() 
for subst in ${substlist}; do 
    filters+=(-e "s/$subst/modified_$subst/") 
done 
sed "${filters[@]}" "$input" > "$output" 

(引用符で囲まれていないパラメータ展開を反復し、動的に各sedフィルタを作成すると、この回答の範囲を超えての質問。)