コマンドラインを使用してテキストファイル内の特定の単語を検索および置換するにはどうすればよいですか?
sed -i 's/original/new/g' file.txt
説明:
sed
= Stream EDitor-i
=インプレース(つまり、元のファイルに保存する)コマンド文字列:
s
=代替コマンドoriginal
=置換するWord(またはWord自体)を記述する正規表現new
=置換するテキストg
= global(つまり、最初の出現だけでなくすべてを置換)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
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
ExモードでVimを使用できます。
ex -s -c '%s/OLD/NEW/g|x' file
%
すべての行を選択
s
代替
g
は、各行のすべてのインスタンスを置き換えます
x
変更が行われた場合(書き込みがある場合)書き込み、終了する
それを達成する方法は多数あります。文字列の置換で達成しようとするものの複雑さや、ユーザーが使い慣れているツールによっては、他の方法よりも好ましい方法もあります。
この回答では、ここで提供されるすべての例をテストするために使用できる単純なinput.txt
ファイルを使用しています。ファイルの内容:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
Bashは実際にはテキスト処理を意図したものではありませんが、単純な置換は parameter expansion を使用して実行できます。特にここでは、単純な構造${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
が使用される理由に興味がある場合、それは基本的に行ごとにファイルを読み取るシェルの方法です。参考として this を参照してください。
テキスト処理ユーティリティであるAWKは、このようなタスクに非常に適しています。 正規表現 に基づいて、単純な置換とより高度な置換を実行できます。 sub()
とgsub()
の2つの関数を提供します。最初のものは最初の出現のみを置換し、2番目は文字列全体の出現を置換します。たとえば、文字列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()
関数があり、より高度な置換に使用できます。
sed
は streameditor 、|
(パイプ)を使用して標準ストリーム(具体的にはSTDINおよびSTDOUT)をsed
経由で送信し、プログラムで即座に変更できるため、Unix哲学の伝統で便利なツールになります。下記の-i
パラメーターを使用して、ファイルを直接編集することもできます。
以下を考慮してください:
sed -i -e 's/few/asd/g' hello.txt
s/
を使用して、s見つかった式few
をasd
に置き換えます。
少数、勇敢な。
Asd、勇敢。
/g
は「グローバル」の略で、行全体でこれを行うことを意味します。 /g
を省略した場合(s/few/asd/
を使用すると、常に3つのスラッシュが必要です)、few
が同じ行に2回出現し、最初のfew
のみがasd
に変更されます。
少数の男性、少数の女性、勇敢な人。
Asdの男性、少数の女性、勇敢な人。
これは、行の先頭の特殊文字を変更するなど、状況によって便利です(たとえば、電子メールスレッドで以前の素材を引用するために使用する大なり記号を水平タブに置き換え、引用された代数の不等式を行の後半に置きます)ただし、anywherefew
が発生するように指定した例では、置換する必要があります。その/g
があることを確認してください。
次の2つのオプション(フラグ)は、1つに結合されます-ie
:
-i
オプションは、ファイルhello.txt
のinプレースを編集するために使用されます。
-e
オプションは、実行するexpression/command、この場合は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]は検索するファイルです