回答:
sed -i 's/original/new/g' file.txt
説明:
sed
= Stream EDitor-i
=インプレース(つまり、元のファイルに保存する)コマンド文字列:
s
=代替コマンドoriginal
=置換する単語(または単語自体)を記述する正規表現new
=置換するテキストg
= global(つまり、最初の出現だけでなくすべてを置換)file.txt
=ファイル名
/
一致する必要のある具体的な文字である場合、セパレータとして他の文字を使用できます(例:)'s_old/text_new/text_g'
。それ以外の場合は、の\
前にaを置い$ * . [ \ ^
てリテラル文字を取得できます。
sed -i '.bak' 's/original/new/g' file.txt
はsed -i '' 's/original/new/g' file.txt
、長さゼロの拡張子を使用して実行することもできますが、バックアップは生成されません。
これを行うには、さまざまな方法があります。1つはsed
正規表現を使用しています。SEDは、テキストをフィルタリングおよび変換するためのストリームエディターです。一例は次のとおりです。
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
パイプよりも意味が< strin
あり> strout
、パイプを使用する別の方法です!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog
cat
でcat file | sed '...'
あることに注意してください。直接言うことができますsed '...' file
。
sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
ます。ファイルを大量に取得し、バックアップを作成しながら2つの変更をその場で行います。time bash -c "$COMMAND"
時間を使用すると、このバージョンは約5倍高速であることが示唆されます。
それを達成する方法は多数あります。文字列の置換で達成しようとするものの複雑さや、ユーザーが使い慣れているツールによっては、他の方法よりも好ましい方法もあります。
この回答ではinput.txt
、ここで提供されるすべての例をテストするために使用できる単純なファイルを使用しています。ファイルの内容:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
Bashは実際にはテキスト処理を意図したものではありませんが、単純な置換はパラメーター展開を介して行うことができます${parameter/old_string/new_string}
。特にここでは単純な構造を使用できます。
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
この小さなスクリプトはインプレース置換を行いません。つまり、新しいテキストを新しいファイルに保存し、古いファイルを削除する必要があります。または mv new.txt old.txt
サイドノート:なぜwhile IFS= read -r ; do ... done < input.txt
使われるのか興味があるなら、それは基本的に行ごとにファイルを読むシェルの方法です。参照用にこれを参照してください。
テキスト処理ユーティリティであるAWKは、このようなタスクに非常に適しています。正規表現に基づいて、単純な置換とより高度な置換を実行できます。2つの機能を提供します:sub()
とgsub()
。最初のものは最初の出現のみを置換し、2番目は文字列全体の出現を置換します。たとえば、stringがある場合one potato two potato
、これが結果になります。
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
AWKは入力ファイルを引数として取ることができるため、と同じことをinput.txt
簡単に行うことができます。
awk '{sub(/blue/,"azure")}1' input.txt
使用しているAWKのバージョンに応じて、インプレース編集を行う場合と行わない場合があります。したがって、通常は新しいテキストを保存して置換します。たとえば、次のようなものです。
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
Sedはラインエディターです。正規表現も使用しますが、単純な置換を行うには十分です:
sed 's/blue/azure/' input.txt
このツールの良いところは、その場で編集できること-i
です。これはフラグで有効にできます。
Perlは、テキスト処理によく使用される別のツールですが、汎用言語であり、ネットワーキング、システム管理、デスクトップアプリ、およびその他の多くの場所で使用されます。C、sed、awkなどの他の言語から多くの概念/機能を借用しました。単純な置換は次のように実行できます。
perl -pe 's/blue/azure/' input.txt
sedと同様に、perlにも-iフラグがあります。
この言語は非常に用途が広く、さまざまなアプリケーションでも使用されています。文字列を操作するための多くの関数がありますがreplace()
、その中にのような変数があればvar="Hello World"
、var.replace("Hello","Good Morning")
ファイルを読み取り、その中の文字列を置き換える簡単な方法は次のようになります。
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
ただし、Pythonでは、新しいファイルに出力する必要もあります。これは、スクリプト自体からも実行できます。たとえば、ここに簡単なものがあります:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
このスクリプトはinput.txt
、コマンドライン引数として呼び出されます。コマンドライン引数でPythonスクリプトを実行する正確なコマンドは次のようになります
$ ./myscript.py input.txt
または
$ python ./myscript.py input.txt
もちろん、それ./myscript.py
が現在の作業ディレクトリにあることを確認し、最初の方法では、それが実行可能に設定されていることを確認してくださいchmod +x ./myscript.py
Pythonには正規表現を含めることもできre
ます。特に、re.sub()
より高度な置換に使用できる機能を持つモジュールがあります。
tr
UNIXでのコマンド
tr
もう一つの素晴らしいツールですが、それは例えば(文字のセットを交換するためのものであることに注意してくださいtr abc cde
翻訳するでしょうa
にc
、b
とd
それはのように単語全体を交換するとは少し異なっている。sed
またはpython
awkのgsubコマンドにより、
awk '{gsub(/pattern/,"replacement")}' file
例:
awk '{gsub(/1/,"0");}' file
上記の例では、1が配置された列に関係なく、すべての1が0に置き換えられます。
特定の列で置換を行う場合は、次のようにします。
awk '{gsub(/pattern/,"replacement",column_number)}' file
例:
awk '{gsub(/1/,"0",$1);}' file
最初の列でのみ1を0に置き換えます。
Perlを介して、
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar
inotifywait
下でファイルを見てsh
、CSV形式でデータを報告しています(カスタム形式にはバグがあるため)。次に、シェルスクリプトでCSVドキュメントを処理する簡単な方法はないと考えました。そこで、CSVを解析して報告するための非常に簡単なスクリプトを開始しました。CSVの仕様を読んで、予想よりも精巧で、二重引用符で囲まれた複数行の値をサポートしていることに気付きました。私はsed
トークン化に頼っていましたが、sed
マルチラインと呼ばれるものでさえ最大2行であることにすぐに気付きました。CSV値の1つが3行以上にわたる場合はどうなりますか?
sed
あるS tream 編 itor、あなたが使用できるように|
送信する(パイプ)を標準ストリームを通じて(STDINとSTDOUT、具体的に)sed
、それUnixの哲学の伝統で便利なツール作り、その場でプログラム的にそれらを改変すること。-i
下記のパラメーターを使用して、ファイルを直接編集することもできます。
以下を考慮してください:
sed -i -e 's/few/asd/g' hello.txt
s/
は、見つかった式を次のように置き換えるために使用されます。few
asd
少数の、勇敢な。
asd、勇敢。
/g
これは「グローバル」の略で、行全体でこれを行うことを意味します。あなたがオフのままにしておくと/g
(とs/few/asd/
、そこには常にどんな3つのスラッシュがないように必要)とfew
同じ行に2回出現し、最初はfew
に変更されますasd
:
少数の男性、少数の女性、勇敢な人。
asdの男性、少数の女性、勇敢な人。
これは、行の先頭にある特殊文字を変更するなど、状況によって便利です(たとえば、電子メールスレッドで以前の素材を引用するために使用する大なり記号を水平タブに置き換え、引用された代数の不等式を行の後半に残すなど)ただし、どこでも few
発生するように指定する例では、置換する必要があります/g
。
次の2つのオプション(フラグ)は1つに結合されます-ie
:
-i
オプションは、編集するために使用され、私は n個のファイルに配置しますhello.txt
。
-e
オプションを示し電子のこのような場合には、実行するためのXPRESSION /コマンドをs/
。
注:-i -e
検索/置換に使用することが重要です。行う場合は-ie
、文字「e」が追加されたすべてのファイルのバックアップを作成します。
このようにすることができます:
locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g"
例:Locateコマンドの結果であるすべてのファイルで[logdir '、' ']([]なし)を[logdir'、os.getcwd()]にすべて置換するには、次のようにします。
ex1:
locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"
ex2:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
[tensorboard / program.py]は検索するファイルです
logdir', ''
-> /logdir', os.getcwd()
)により、この回答の解析が難しくなります。また、sed onを使用するファイルは、質問の一部ではないため、最初に答えを見つけることを指定する価値があります。