map.txt
たとえば、検索文字列とその代替項目のリストを含むファイルがあります。
search -> replacement
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
シンボリックリンクを除いて、フォルダ内のすべてのファイルに対して上記と一致するすべての文字列を再帰的に検索して置き換える必要があります。私は次のように一度に1つずつ行う方法を知っています。
$ find /some/folder -type f -exec sed -i 's/old_text/new_text/g' {} \;
上記のマッピングを使用して大規模にこれを行うにはどうすればよいですか?私が読んでこの問題でも、よく理解できません。
ベストアンサー1
回答
速度に興味がない場合(ワンタイム作業)、次のことを試すことができます。
cat map.txt | while read line; do
neww=${line##* };
oldw=${line%% *};
find /some/folder -type f -exec sed -i "s/$oldw/$neww/g" {} \;
done
私はこれが最善の選択ではないことを知っています...:-P
PS:テストフォルダをチェックして機能していることを確認してください!
説明する
オリジナル:
- 猫ファイルmap.txt。
- 各行を読み、置き換える単語
$oldw
と置き換える内容を学びます$neww
。 - 各ペアに対してすでに使用したfindコマンドを実行します(今回は変数の置換を許可するために二重引用符を参照してください)。
パラメータ拡張情報
変数を設定するには、各行の最初の単語と最後の単語を取得する必要があります$oldw
。$neww
これを行うには、パラメータ拡張(純粋なBash実装)を使用しますが、文字列の最初の単語と最後の単語(またはcut
)awk
を取得するために別の方法を使用することもできます。
${line##* }
:変数からline
最大のプレフィックス(double#
)パターンを削除します。ここで、パターンは文字(*
)の後にスペース()が続きますline
。${line%% *}
:変数からline
最大のサフィックス(double)パターンを削除します%
。ここで、パターンはスペース(*
)が続きます。このようにして、私たちは最初の言葉を得ますline
。
この例では、単語はスペースで区切られていますが、どの区切り文字でも使用できます。