2016-12-31 4 views
0

ファイル内の不正なパス名(pathname1)を持つ特定の場所(/subdirectory1)に数十のbashスクリプトがあります。私はどういうわけか、そのサブディレクトリ内のすべてのbashスクリプト*.shに対して、このパス名をpathname2に置き換えたいと思います。複数のファイルに対して文字列置換を実行する方法は?

標準的な方法はありますか? Perlで

、私は単一のファイルfile1で働いていたならば、私は実行します:

perl -pi -e 's/pathname1/pathname2/g' file1 

どのようにして、すべてのファイル、*.shのためにこれを達成するのでしょうか?

これはperlである必要はありませんが、これが心に浮かぶ1つの方法です。他のシェルスクリプトや他の言語でこれを行う方法もあると私は思っています---私はこの質問を編集してオプションを絞り込むことを喜んで行います。

+1

'file1'を' * .sh'に変更しますか?あなたの質問は本当に不明です。 –

+1

確かに 'perl -pi -e 's/path1/path2/g' * .sh'はそのトリックを行います –

+0

@WilliamPursellそれは機能しますか? ...私はばかだよ – ShanZhengYang

答えて

2

は、単にファイルグロブを使用しています。

2

あなたはまず彼らにperlまたはsedまたは何を実行し、ファイルを一覧表示するfindを実行することができます:find出力のそれぞれのためにこれを実行する意味

find . -name '*.sh' -exec <perl_command> {} \; 

{} \;を、。

perl -pi -e '[email protected]@[email protected]' *.sh 

これはうまく空白文字が含まれている病的なファイル名に対処します:

+0

あなたは ''の意味を指定するべきです( '-name" * .sh "'としますが、 ''はかなり自明です)。 –

+0

私はそれが質問とは正反対だと思いますが、確かにそうです。一定。 – yelsayed

+0

最後に、 ''が '-name" * .sh "'や '-type 'f''や一般的な使用法を示す何らかの組み合わせかもしれないというような別の注意を考えていました。しかし、それをインラインで置くこともできます。 –

3

ちょうどすべてのファイル名を一覧表示し、それらは全て|がそのようにパスで/をエスケープする必要はありません区切り記号に使用されるライン

perl -pi -e 's|pathname1|pathname2|g' *.sh 

で行を処理しています。

これは、*.shが必要なファイルを指定していることを前提としています。


我々は、これが

LINE: while (defined($_ = <ARGV>)) { 
    '???'; 
} 
-e syntax OK 

これは-MO=Deparseの好意により示される、ワンライナーのコードと等価である出力

perl -MO=Deparse -ne '' file1 file2 

を実行した場合であることがわかります。これはループが入力の上に設定されていることを示しています。これは<ARGV>によって提供されます。

ここで<ARGV>とは何ですか? I/O Operators in perlop

からヌルファイルハンドル<>は特別です:... <>からの入力は、標準入力から、またはコマンドラインにリストされた各ファイルのいずれかから来ています。

<>

<ARGV>だから入力がすべて提出されたファイルからすべての行であることを行っているため、単に同義語である

関連する問題