コマンドを使用したファイル内のテキストの検索と置換

コマンドラインを使用してテキストファイル内の特定の単語を検索して置き換えるにはどうすればよいですか?

sed -i 's/original/new/g' file.txt

説明:

  • sed =ストリームエディタ
  • -i =インプレース(つまり、元のファイルに保存します)
  • コマンド文字列:

    • s =代替コマンド
    • original =置換する単語(または単に単語自体)を記述する正規表現
    • new =それを置き換えるテキスト
    • g =グローバル(つまり、最初の出現だけでなく、すべてを置き換えます)
  • file.txt =ファイル名

それを達成するための多くの方法があります。 文字列置換で何を達成しようとするかの複雑さや、ユーザーが慣れ親しんでいるツールによっては、他の方法よりもいくつかの方法が優先される場合があ

この回答では、私は単純なものを使用しています input.txt ここで提供されているすべての例をテストするために使用できるファイル。 ファイルの内容:

roses are red , violets are blueThis is an input.txt and this doesn't rhyme

バッシュ

Bashは実際にはテキスト処理のためのものではありませんが、単純な置換は次の方法で行うことができます パラメータ展開 、特にここでは単純な構造を使用することができます ${parameter/old_string/new_string}.

#!/bin/bashwhile IFS= read -r linedo    case "$line" in       *blue*) printf "%s\n" "${line/blue/azure}" ;;       *) printf "%s\n" "$line" ;;    esacdone < input.txt

つまり、新しいテキストを新しいファイルに保存し、古いファイルを削除する必要があります。 mv new.txt old.txt

サイドノート:あなたが理由について興味があるなら while IFS= read -r ; do ... done < input.txt これは基本的にシェルのファイルを1行ずつ読み取る方法です。 参照 この 参考のために。

AWK

テキスト処理ユーティリティであるAWKは、このような作業には非常に適しています。 それは簡単な取り替えおよび基づいてはるかに高度の物をすることができます 正規表現. それは2つの機能を提供します: sub()gsub(). 最初のものは最初の出現のみを置き換え、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はラインエディタです。 また、正規表現を使用しますが、単純な置換の場合は次のようにすれば十分です:

sed 's/blue/azure/' input.txt

このツールの良い点は、インプレース編集があり、有効にすることができることです -i 旗。

Perl

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 pythonimport sysimport osimport tempfiletmp=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 そして正規表現。 SEDは、テキストのフィルタリングと変換のためのストリームエディタです。 その一例は次のとおりです:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog

よりも理にかなっているかもしれない別の方法 < strin> strout パイプ付きです!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@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は、それが配置された列に関係なく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
  1. % すべての行を選択

  2. s 代用品

  3. g 各行のすべてのインスタンスを置き換えます

  4. x 変更が行われた場合(変更が行われた場合)に書き込み、終了します

sed は、 sトレーム エドイトル、あなたが使用できるという点で | (パイプ)を送信するには 標準ストリーム (具体的にはSTDINとSTDOUT)を介して sed そして、それをUnix哲学の伝統で便利なツール作り、その場でプログラムでそれらを変更します。 -i パラメータは以下の通りです。
次の点を考慮してください:

sed -i -e 's/few/asd/g' hello.txt

s/ に使用されます s発見された式をubstituteします fewasd:

少数の、勇敢な。


Asd、勇敢な。

/g "global"の略で、行全体でこれを行うことを意味します。 あなたがオフに残す場合 /g (と s/few/asd/、何があっても常に三つのスラッシュが必要です)と few 同じ行に二度表示され、最初の行だけが表示されます few に変更されます asd:

少数の男性、少数の女性、勇敢な。


Asdの男性、少数の女性、勇敢な。

これは、行の先頭に特殊文字を変更するなどの状況で便利です(たとえば、電子メールスレッドの前の資料を水平タブで引用するために使用する大なり どこでも few それは交換する必要があります発生し、あなたがそれを持っていることを確認してください /g.

次の2つのオプション(フラグ)は1つに結合されます, -ie:

-i オプションは編集に使用されます iファイルにn個の場所を指定します。 hello.txt.

-e オプションは、 eこの場合、実行するxpression/コマンド s/.

注:あなたが使用することが重要です -i -e 検索/置換する。 あなたが行う場合 -ie、文字'e'が追加されたすべてのファイルのバックアップを作成します。

あなたはこのようにすることができます:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

例:すべての出現[logdir','']([]なし)を[logdir',osに置き換える。getcwd()]locateコマンドの結果であるすべてのファイルで、次の操作を行います:

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]は検索するファイルです