web-dev-qa-db-ja.com

コマンドを使用してファイル内のテキストを検索および置換する

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

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

説明:

  • sed = Stream EDitor
  • -i =インプレース(つまり、元のファイルに保存する)
  • コマンド文字列:

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

1031
cscarney

これを行うには、さまざまな方法があります。 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
32
Marco Ceppi

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
21
Avinash Raj

ExモードでVimを使用できます。

ex -s -c '%s/OLD/NEW/g|x' file
  1. %すべての行を選択

  2. s代替

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

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

21
Steven Penny

それを達成する方法は多数あります。文字列の置換で達成しようとするものの複雑さや、ユーザーが使い慣れているツールによっては、他の方法よりも好ましい方法もあります。

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

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

BASH

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

テキスト処理ユーティリティである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はラインエディターです。正規表現も使用しますが、単純な置換を行うには十分です:

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

このツールの良い点は、インプレース編集ができることです。これは、-iフラグで有効にできます。

Perl

Perlは、テキスト処理によく使用される別のツールですが、汎用言語であり、ネットワーク、システム管理、デスクトップアプリ、および他の多くの場所で使用されます。 C、sed、awkなどの他の言語から多くの概念/機能を借用しました。単純な置換は次のように実行できます。

Perl -pe 's/blue/Azure/' input.txt

Sedと同様に、Perlにも-iフラグがあります。

Python

この言語は非常に用途が広く、さまざまなアプリケーションでも使用されています。文字列を操作するための多くの関数があり、その中には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()関数があり、より高度な置換に使用できます。

21

sedstreameditor|(パイプ)を使用して標準ストリーム(具体的にはSTDINおよびSTDOUT)をsed経由で送信し、プログラムで即座に変更できるため、Unix哲学の伝統で便利なツールになります。下記の-iパラメーターを使用して、ファイルを直接編集することもできます。
以下を考慮してください

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

s/を使用して、s見つかった式fewasdに置き換えます。

少数、勇敢な。


Asd、勇敢。

/gは「グローバル」の略で、行全体でこれを行うことを意味します。 /gを省略した場合(s/few/asd/を使用すると、常に3つのスラッシュが必要です)、fewが同じ行に2回出現し、最初のfewのみがasdに変更されます。

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


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

これは、行の先頭の特殊文字を変更するなど、状況によって便利です(たとえば、電子メールスレッドで以前の素材を引用するために使用する大なり記号を水平タブに置き換え、引用された代数の不等式を行の後半に置きます)ただし、anywherefewが発生するように指定した例では、置換する必要があります。その/gがあることを確認してください。

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

-iオプションは、ファイルhello.txtinプレースを編集するために使用されます。

-eオプションは、実行するexpression/command、この場合はs/を示します。

注:検索/置換には-i -eを使用することが重要です。 -ieを実行すると、文字「e」が追加されたすべてのファイルのバックアップが作成されます。

8

このようにすることができます:

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

2