与えられた入力文字列を検索して置換する最も簡単な方法は何ですか?abc
、別の文字列を置換する(ファイル/tmp/file.txt
内のXYZ
)
私はSSHを介してコマンドを実行するためにアプリを書いてIronPythonを使用しています - しかし私はUnixをよく知らないので何を探すべきかわかりません。
Bashは、コマンドラインインターフェイスであることとは別に、非常に強力なスクリプト言語になることができると聞いたことがあります。だから、これが本当なら、私はあなたがこれらのような行動を実行できると思います。
Bashでそれを行うことができますか、そして私の目標を達成するための最も簡単な(1行の)スクリプトは何ですか?
最も簡単な方法はsed(またはPerl)を使うことです。
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
-i
オプションにより、sedを呼び出してインプレース編集を行います。これはbashから呼び出すことができます。
本当にbashだけを使いたいのであれば、次のようにします。
while read a ; do echo ${a//abc/XYZ} ; done < /tmp/file.txt > /tmp/file.txt.t ; mv /tmp/file.txt{.t,}
これは各行をループして置換をし、一時ファイルに書き込みます(入力を壊したくない)。最後の移動は一時的に元の名前に移動します。
ファイル操作は通常Bashによって行われるのではなく、Bashによって呼び出されたプログラムによって行われます。
> Perl -pi -e 's/abc/XYZ/g' /tmp/file.txt
-i
フラグはインプレース置換をするようにそれに伝えます。
元のファイルのバックアップを取る方法など、詳細についてはman perlrun
を参照してください。
私はこれにつまずいたので驚きました...
"replace" パッケージに同梱されている "mysql-server" というコマンドがありますので、インストールしていれば試してみてください。
# replace string abc to XYZ in files
replace "abc" "XYZ" -- file.txt file2.txt file3.txt
# or pipe an echo to replace
echo "abcdef" |replace "abc" "XYZ"
詳しくは man replace を参照してください。
これは古い投稿ですが、@ centurianが一重引用符は何も展開されないことを意味しているので、変数を使用したい人のためのものです。
変数を取得する簡単な方法は、文字列の連結を行うことです。これはbashの並置によって行われるため、次のように動作するはずです。
sed -i -e 's/'"$var1"'/'"$var2"'/g' /tmp/file.txt
Bashは他のシェルと同様に、他のコマンドを調整するための単なるツールです。通常は標準のUNIXコマンドを使おうとしますが、もちろんBashを使って自分のコンパイル済みプログラム、他のシェルスクリプト、Python、Perlスクリプトなどを呼び出すこともできます。
この場合、それを実行する方法がいくつかあります。
ファイルを読み、それを別のファイルに書き込み、あなたが行っているように検索/置換をしたいのなら、sedを使います。
sed 's/abc/XYZ/g' <infile >outfile
ファイルをその場で編集したい場合(ファイルをエディタで開いて編集してから保存する場合)、行エディタ 'ex'に指示を与えます。
echo "%s/abc/XYZ/g
w
q
" | ex file
Exはフルスクリーンモードのないviのようなものです。あなたはviの ':'プロンプトと同じコマンドを与えることができます。
このスレッドを他の人の間で見つけました、そしてそれが最も完全な答えを含んでいることに同意するので私も追加します:
1)sedとedはとても便利です...手で! @Johnnyからのこのコードを見てください。
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
2)私の制限がシェルスクリプトでそれを使用することである場合、abcやXYZの代わりに変数を内部で使用することはできません。 これ 少なくとも私が理解していることと一致するようです。だから、私は使用することはできません:
x='abc'
y='XYZ'
sed -i -e 's/$x/$y/g' /tmp/file.txt
#or,
sed -i -e "s/$x/$y/g" /tmp/file.txt
しかし、私たちは何ができますか? @Johnnyは「while read ...」を使用すると述べたが、残念ながらこれで話は終わりではない。以下は私とうまくいった:
#edit user's virtual domain
result=
#if nullglob is set then, unset it temporarily
is_nullglob=$( shopt -s | egrep -i '*nullglob' )
if [[ is_nullglob ]]; then
shopt -u nullglob
fi
while IFS= read -r line; do
line="${line//'<servername>'/$server}"
line="${line//'<serveralias>'/$alias}"
line="${line//'<user>'/$user}"
line="${line//'<group>'/$group}"
result="$result""$line"'\n'
done < $tmp
echo -e $result > $tmp
#if nullglob was set then, re-enable it
if [[ is_nullglob ]]; then
shopt -s nullglob
fi
#move user's virtual domain to Apache 2 domain directory
......
3)nullglobが設定されているかどうかがわかるように、*を含む文字列があると奇妙に振る舞います。
<VirtualHost *:80>
ServerName www.example.com
になる
<VirtualHost ServerName www.example.com
最後の山括弧はなく、Apache2もロードできません。
4)この種の構文解析は、1ヒット検索と置換より遅くなるはずですが、すでに見たように、1つの解析サイクルのうち4つの異なる検索パターンに対して4つの変数があります。
私は問題の与えられた仮定で考えることができる最も適切な解決策。
Sedが使えます
sed -i 's/abc/XYZ/gi' /tmp/file.txt
大文字と小文字を区別しない に-i
を使用してください。検索するテキストがabc
またはABC
またはAbC
などであることがわからない場合.
ファイル名がわからなくてもfind
とsed
を使えます。
find ./ -type f -exec sed -i 's/abc/XYZ/gi' {} \;
すべてのpythonファイルで見つけて置き換えます。
find ./ -iname "*.py" -type f -exec sed -i 's/abc/XYZ/gi' {} \;
Edコマンドを使ってファイル内検索や置換をすることもできます。
# delete all lines matching foobar
ed -s test.txt <<< $'g/foobar/d\nw'
URLを "/"文字に置き換える場合は注意してください。
それを行う方法の例:
sed -i "s%http://domain.com%http://www.domain.com/folder/%g" "test.txt"
抽出元: http://www.sysadmit.com/2015/07/linux-reemplazar-texto-en-archivos-con-sed.html
作業中のファイルがそれほど大きくなく、一時的に変数に格納しても問題ない場合は、ファイル全体に一度にBash文字列置換を使用できます。1行ずつ移動する必要はありません。
file_contents=$(</tmp/file.txt)
echo "${file_contents//abc/XYZ}" > /tmp/file.txt
ファイル全体の内容は、改行を含めて1つの長い文字列として扱われます。
XYZは$replacement
などの変数にすることができます。ここでsedを使用しないことの利点の1つは、検索または置換文字列にsedパターンの区切り文字が含まれる可能性があるということです。欠点は、正規表現やsedのより洗練された操作を使用できないことです。
次のシェルコマンドを試してください。
find ./ -type f -name "file*.txt" | xargs sed -i -e 's/abc/xyz/g'
ファイル内のテキストを非対話的に編集するには、vimなどのインプレーステキストエディタが必要です。
これは、コマンドラインから使用する簡単な例です。
vim -esnc '%s/foo/bar/g|:wq' file.txt
これは @slim answer of ex editorと同じで、基本的に同じものです。
ここにいくつかのex
実用的な例があります。
ファイル内のテキストfoo
をbar
に置き換えます。
ex -s +%s/foo/bar/ge -cwq file.txt
複数のファイルから末尾の空白を削除する:
ex +'bufdo!%s/\s\+$//e' -cxa *.txt
トラブルシューティング(端末が動かなくなった場合):
-V1
パラメータを追加します。-cwq!
で強制終了してください。また見なさい:
あなたはbashスクリプト内でもpythonを使うことができます。私はここでいくつかの主な答えであまり成功していませんでした、そしてこれがループを必要とせずに動作することがわかりました:
#!/bin/bash
python
filetosearch = '/home/ubuntu/ip_table.txt'
texttoreplace = 'tcp443'
texttoinsert = 'udp1194'
s = open(filetosearch).read()
s = s.replace(texttoreplace, texttoinsert)
f = open(filetosearch, 'w')
f.write(s)
f.close()
quit()
あなたはrplコマンドを使用することができます。たとえば、phpプロジェクト全体でドメイン名を変更したいとします。
rpl -ivRpd -x'.php' 'old.domain.name' 'new.domain.name' ./path_to_your_project_folder/
これは明確な原因の対立ではありませんが、非常に迅速で便利です。 :)