如何使此命令安全,并适用于带引号的字符串



我找到(并稍微调整了一下)一个命令来编辑使用正则表达式(和perl)的文件列表。我把它放到一个名为 cred 的脚本文件中,这样我就可以cred . england England将当前目录中所有文件中出现的所有england替换为England

find $1 -type f -exec perl -e 's/'$2'/'$3'/g' -p -i {} ;

它是邪恶的,强大的,已经有用了——但危险,有缺陷。我希望它...

  1. 首先预览更改(或至少操作的文件),要求确认
  2. 处理比单个单词更长的字符串。我尝试了cred . england 'the United Kingdom'但失败

我也会对其他(简短而令人难忘的,在osx和ubuntu上普遍安装/安装)命令感兴趣,以实现同样的事情。

编辑:

这就是我到目前为止所拥有的 - 对改进持开放态度......

# highlight the spots that will be modified (not specifying the file)
find $1 -type f -exec grep -E "$2" --color {} ;
# get confirmation
read -p "Are you sure? " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
  # make changes, and highlight the spots that were changed
  find $1 -type f -exec perl -e "s/$2/$3/g" -p -i {} ;
  echo ""
  find $1 -type f -exec grep -E "$3" --color {} ;
else
  echo ""
  echo "Aborted!!"
fi

要处理带有空格的字符串,请编写如下命令:

perl -e "s/$2/$3/g"

如果使用双引号,变量将在引号内展开。

要执行预览更改并请求确认之类的操作,您将需要一个更复杂的脚本。 一个非常简单的事情是先运行find $1 -type f以获取所有文件的列表,然后使用 read 命令获取一些输入并决定是否应该继续。

这是一个使用 File::Find 的纯 Perl 版本。 它相当长,但更容易调试和做更复杂的事情。 它适用于每个文件,可以更轻松地进行验证。

use strict;
use warnings;
use autodie;
use File::Find;
use File::Temp;
my($Search, $Replace, $Dir) = @ARGV;
# Useful for testing
run($Dir);
sub run {
    my $dir = shift;
    find &replace_with_verify, $dir;
}
sub replace_with_verify {
    my $file = $_;
    return unless -f $file;
    print "File: $filen";
    if( verify($file, $Search) ) {
        replace($file, $Search, $Replace);
        print "nReplaced: $filen";
        highlight($file, $Replace);
    }
    else {
        print "Ignoring $filen";
    }
    print "n";
}
sub verify {
    my($file, $search) = @_;
    highlight($file, $search);
    print "Are you sure? [Yn] ";
    my $answer = <STDIN>;
    # default to yes
    return 0 if $answer =~ /^n/i;
    return 1;
}
sub replace {
    my($file, $search, $replace) = @_;
    open my $in, "<", $file;
    my $out = File::Temp->new;
    while(my $line = <$in>) {
        $line =~ s{$search}{$replace}g;
        print $out $line;
    }
    close $in;
    close $out;
    return rename $out->filename, $file;
}
sub highlight {
    my($file, $pattern) = @_;
    # Use PCRE grep.  Should probably just do it in Perl to ensure accuracy.
    system "grep", "-P", "--color", $pattern, $file;    # Should probably use a pager
}

相关内容

  • 没有找到相关文章

最新更新