0

フォルダー、サブフォルダー、およびファイルがあるプロジェクトがあります。各ファイルで Masi という単語を Bond という単語に置き換える必要があります。

次の replace という Sed スクリプトの実行に失敗しました

s/Masi/Bond/

Zshで

sed -f PATH/replace PATH2/project/**

出力として、Masi を含まないファイルも含め、すべてのファイルが表示されます。

Sed は、必ずしもタスクに最適なツールではありません。Python と Perl に興味があります。

ファイルの内容のみが変更されるように、Sed/Perl/Python でどのように置換しますか?

4

5 に答える 5

12

現在のディレクトリとサブディレクトリにあるすべてのファイルの単語を置き換えるには

perl -p -i -e 's/Masi/Bond/g' $(grep -rl Masi *)

ファイル名にスペースが含まれている場合、上記は機能しません。より安全に行うには:

find . -type f -exec perl -p -i -e 's/Masi/Bond/g' {} \;

またはファイル名にスペースが含まれる Mac の場合

find . -type f -print0 | xargs -0 perl -p -i -e 's/Masi/Bond/g'

説明

  • -p は print または die を意味します
  • -i は「バックアップファイルを作成しない」ことを意味します
  • -e を使用すると、コマンド ラインで perl コードを実行できます
于 2009-05-21T20:03:13.363 に答える
3

ファイルでいっぱいのフォルダーの名前を変更する:

use warnings;
use strict;
use File::Find::Rule;

my @list = File::Find::Rule->new()->name(qr/Masi/)->file->in('./');

for( @list ){
   my $old = $_;
   my $new = $_;
   $new =~ s/Masi/Bond/g;
   rename $old , $new ;
}

ファイル内の文字列の置換

use warnings;
use strict;
use File::Find::Rule;
use File::Slurp;
use File::Copy;

my @list = File::Find::Rule->new()->name("*.something")->file->grep(qr/Masi/)->in('./');

for( @list ){
   my $c = read_file( $_ );
   if ( $c =~ s/Masi/Bond/g; ){
    File::Copy::copy($_, "$_.bak"); # backup.
    write_file( $_ , $c );
   }
}
  • strict (core) - 安全でない構造を制限する Perl プラグマ
  • warnings (core) - オプションの警告を制御する Perl プラグマ
  • File::Find::Rule - File::Find の代替インターフェース
  • File::Find (コア) - ディレクトリ ツリーをトラバースします。
  • File::Slurp - 完全なファイルの効率的な読み書き
  • File::Copy (コア) - ファイルまたはファイルハンドルをコピーする
于 2009-05-21T20:30:43.010 に答える
3

-iオプション ( man sed) を sed に渡して、それで完了しないのはなぜですか? ファイル内に Masi が見つからない場合、ファイルは変更されずに書き換えられます。または、何か不足していますか?

ファイルの内容をインラインで置き換えたくない場合 (これは-iが行うことです)、現在とまったく同じように行うことができますが、その前にgrep&をスローします。xargs

grep -rl Masi PATH/project/* | xargs sed -f PATH/replace

多くのオプションがありますが、これには perl スクリプト全体を記述しないでください(ワンライナーにはパスを与えます ;))。 findgrepsedxargsなどは常により柔軟になります。

コメントへの応答:

grep -rl Masi PATH/project/* | xargs sed -n -e '/Masi/ p'
于 2009-05-21T20:02:50.603 に答える
0
import glob
import os

# Change the glob for different filename matching 
for filename in glob.glob("*"):
  dst=filename.replace("Masi","Bond")
  os.rename(filename, dst)
于 2009-06-02T18:52:01.547 に答える
0

Windows でテストされたソリューション

CPAN モジュール File::Slurp が必要です。標準の Unix シェル ワイルドカードで動作します。./replace.pl PATH/replace.txt PATH2/replace* のように

#!/usr/bin/perl

use strict;
use warnings;
use File::Glob ':glob';
use File::Slurp;
foreach my $dir (@ARGV) {
  my @filelist = bsd_glob($dir);
  foreach my $file (@filelist) {
    next if -d $file;
    my $c=read_file($file);
    if ($c=~s/Masi/Bond/g) {
      print "replaced in $file\n";
      write_file($file,$c);
    } else {
      print "no match in $file\n";
    }
  }
}
于 2009-05-21T20:05:43.653 に答える