ssh
サーバーへのアクセスのみで、フォルダー内の多くのファイルの文字列を置き換える必要があります。これどうやってするの?
27 に答える
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
「foo」の出現は「bar」に置き換えられます。
-i '.bak'
macOS などの BSD システムでは、マンページごとに「リスク破損または部分的なコンテンツ」のようなバックアップ拡張機能を提供する必要があります。
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
Kaspar の回答に似ていますが、g フラグを使用して行上のすべての出現箇所を置き換えます。
find ./ -type f -exec sed -i 's/string1/string2/g' {} \;
大文字と小文字を区別しないグローバルの場合:
find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
これは私のために働いた:
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
しかし、これはしませんでした: sed -i 's/string1/string2/g' *
. おそらく、「foo」はstring1ではなく、「bar」はstring2ではありません。
ファイル内のパスを (エスケープ文字を避けて) 置き換えるには、次のコマンドを使用できます。
sed -i 's@old_path@new_path@g'
@ 記号は、後続の文字列ですべての特殊文字を無視する必要があることを意味します。
使用できるファイルのリストがある場合
replace "old_string" "new_string" -- file_name1 file_name2 file_name3
使用できるファイルがすべて揃っている場合
replace "old_string" "new_string" -- *
拡張子付きのファイルのリストがある場合は、使用できます
replace "old_string" "new_string" -- *.extension
「find と sed を使用することもできますが、この小さな perl の行はうまく機能することがわかりました。
perl -pi -w -e 's/search/replace/g;' *.php
- -e は、次のコード行を実行することを意味します。
- -i はインプレース編集を意味します
- -w 書き込み警告
- -p ループ
" ( http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.phpから抽出)
私の最良の結果は、perlとgrepを使用することから得られます(ファイルに検索式があることを確認するため)
perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' )
この質問(および回答)を見つける前に、私は自分の解決策を考え出しました。「replace」「several」と「xml」のさまざまな組み合わせを検索しました。これが私のアプリケーションだったからですが、この特定のアプリケーションは見つかりませんでした。
私の問題:複雑なオブジェクトを含む、テストケースのデータを含むSpring xmlファイルがありました。Java ソース コードのリファクタリングにより多くのクラスが変更され、xml データ ファイルには適用されませんでした。テスト ケース データを保存するために、いくつかのディレクトリに分散されたすべての xml ファイルのすべてのクラス名を変更する必要がありました。元の xml ファイルのバックアップ コピーを保存している間はすべて (ただし、バージョン管理がここで私を救うので、これは必須ではありませんでした)。
find
+の組み合わせを探してsed
いましたが、他の状況ではうまくいきましたが、一度に複数の置換を行うことはできませんでした。
次に、ubuntu の応答を確認し、コマンド ラインを作成するのに役立ちました。
find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
そして、それは完全に機能しました(まあ、私のケースには6つの異なる代替品がありました). ただし、現在のディレクトリの下にあるすべての *.xml ファイルに影響することに注意してください。そのため、バージョン管理システムに責任がある場合は、最初にフィルタリングしてsed
、必要な文字列を実際に持っているものだけに渡すことをお勧めします。お気に入り:
find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @
-i
ストリーム エディタは、バックアップ ファイルを引数として取るスイッチで呼び出されると、複数のファイルを「インプレース」で変更します。そう
sed -i.bak 's/foo/bar/g' *
このフォルダー内のすべてのファイルで に置き換えfoo
られbar
ますが、サブフォルダーには分類されません。.bak
ただし、これにより、ディレクトリ内のすべてのファイルに対して新しいファイルが生成されます。このディレクトリとそのすべてのサブディレクトリ内のすべてのファイルに対してこれを再帰的に行うにはfind
、ディレクトリ ツリーを走査するための のようなヘルパーが必要です。
find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *
find
必要に応じて などの追加の引数を指定することにより、変更するファイルをさらに制限できますfind ./ -name '*.php' -or -name '*.html' -print0
。
注: GNUsed
はファイルの末尾を必要とせずsed -i 's/foo/bar/g' *
、同様に機能します。FreeBSDsed
は拡張機能を要求しますが、その間にスペースを入れることができるのでsed -i .bak s/foo/bar/g *
機能します。
私の個人的な英語ノードを維持するために、ディレクトリの下のすべてのファイルに対して、古い/新しい文字列の複数のペアを再帰的に置き換えるのに役立つユーティリティ スクリプトを作成しました。
複数の古い/新しい文字列のペアは、ハッシュ マップで管理されます。
dir はコマンド ラインまたは環境変数を介して設定できます。マップはスクリプトにハード コードされていますが、必要に応じてファイルからロードするようにコードを変更できます。
いくつかの新機能のため、bash 4.2 が必要です。
en_standardize.sh:
#! /bin/bash
# (need bash 4.2+,)
#
# Standardize phonetic symbol of English.
#
# format:
# en_standardize.sh [<dir>]
#
# params:
# * dir
# target dir, optional,
# if not specified then use environment variable "$node_dir_en",
# if both not provided, then will not execute,
# *
#
paramCount=$#
# figure target dir,
if [ $paramCount -ge 1 ]; then # dir specified
echo -e "dir specified (in command):\n\t$1\n"
targetDir=$1
elif [[ -v node_dir_en ]]; then # environable set,
echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n"
targetDir=$node_dir_en
else # environable not set,
echo "dir not specified, won't execute"
exit
fi
# check whether dir exists,
if [ -d $targetDir ]; then
cd $targetDir
else
echo -e "invalid dir location:\n\t$targetDir\n"
exit
fi
# initial map,
declare -A itemMap
itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e")
# print item maps,
echo 'maps:'
for key in "${!itemMap[@]}"; do
echo -e "\t$key\t->\t${itemMap[$key]}"
done
echo -e '\n'
# do replace,
for key in "${!itemMap[@]}"; do
grep -rli "$key" * | xargs -i@ sed -i "s/$key/${itemMap[$key]}/g" @
done
echo -e "\nDone."
exit