web-dev-qa-db-ja.com

複数のファイルで検索/置換を行うための最良の方法は?

これを行うための最良の方法は何ですか?私はコマンドラインの戦士ではありませんが、grepcatを使用する方法があるのではないかと考えていました。

フォルダとサブフォルダで発生する文字列を置き換えたいだけです。これを行うための最良の方法は何ですか?それが問題なら、私はubuntuを実行しています。

41
damon
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

その最初の部分は、変更するファイルを見つけるためのfindコマンドです。あなたはそれを適切に修正する必要があるかもしれません。 xargsコマンドは、見つかったすべてのファイルを取得し、それにsedコマンドを適用します。 sedコマンドは、fromのすべてのインスタンスを取得し、それをtoに置き換えます。これは標準の正規表現なので、必要に応じて変更してください。

Svnを使用している場合は注意してください。 .svn-directoriesも検索され、置き換えられます。たとえば、次のようにそれらを除外する必要があります。

find . ! -regex ".*[/]\.svn[/]?.*" -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

または

find . -name .svn -Prune -o -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'
37
Paul Tomblin

Paulが言ったように、最初に編集したいファイルを見つけてから編集したいと思います。 findを使用する代わりに、GNU grep(Ubuntuのデフォルト)を使用することもできます。例:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g'

特定の種類のファイルのみが必要であることがわかっている場合は、ack-grep(Sudo apt-get install ack-grepまたはvisit http://petdance.com/ack/ )を使用することもできます。 、およびバージョン管理ディレクトリ内のものを無視したい。たとえば、テキストファイルのみが必要な場合は、

ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g'
# `from` here is an arbitrary commonly occurring keyword

Sedを使用する代わりに、コマンドごとに複数のファイルを処理できるPerlを使用することもできます。

grep -r -l from . | xargs Perl -pi.bak -e 's/from/to/g'

ここで、Perlはその場で編集するように指示され、最初に.bakファイルを作成します。

好みに応じて、パイプの左側と右側のいずれかを組み合わせることができます。

37
Emil Sit

ag、The Silver Searcher を使用して複数のファイルの検索/置換操作を行う人々のために、別の例を紹介します。

完全な例:

ag -l "search string" | xargs sed -i '' -e 's/from/to/g'

これを分解すると、次のようになります。

# returns a list of files containing matching string
ag -l "search string"

次に、次のようになります。

# consume the list of piped files and prepare to run foregoing command
# for each file delimited by newline
xargs

最後に、文字列置換コマンド:

# -i '' means edit files in place and the '' means do not create a backup
# -e 's/from/to/g' specifies the command to run, in this case,
# global, search and replace

sed -i '' -e 's/from/to/g'
37
doremi

sedの代わりに、rpl --recursive --verbose --whole-words 'F' 'A' grades/のようにrpl(たとえば、 http://rpl.sourceforge.net/ またはGNU/Linuxディストリビューションから入手可能)を使用することもできます。

3
comment() { 
}
doc() { 
}
function agr { 
doc 'usage: from=sth to=another agr [ag-args]'
comment -l --files-with-matches

ag -0 -l "$from" "${@}" | pre-files "$from" "$to"
}
pre-files() {
doc 'stdin should be null-separated list of files that need replacement; $1 the string to replace, $2 the replacement.'
comment '-i backs up original input files with the supplied extension (leave empty for no backup; needed for in-place replacement.)(do not put whitespace between -i and its arg.)'
comment '-r, --no-run-if-empty
              If  the  standard input does not contain any nonblanks,
              do not run the command.  Normally, the command  is  run
              once  even  if there is no input.  This option is a GNU
              extension.'

AGR_FROM="$1" AGR_TO="$2" xargs -r0 Perl -pi.pbak -e 's/$ENV{AGR_FROM}/$ENV{AGR_TO}/g'
}

次のように使用できます。

from=str1 to=sth agr path1 path2 ...

現在のディレクトリを使用するためのパスを指定しないでください。 ag、xargs、およびPerlをPATHにインストールする必要があることに注意してください。

0
HappyFace