【发布时间】:2012-02-17 08:47:21
【问题描述】:
我正在尝试在命令行上进行动态搜索并替换为 Perl,其中部分替换文本是反引号中 grep 命令的输出。这可以在命令行上执行吗,还是我需要编写一个脚本来执行此操作?
这是我认为可以解决问题的命令。我认为 Perl 会将反引号视为命令替换,但它只是将反引号和其中的内容视为字符串:
perl -p -i -e 's/example.xml/http:\/\/exampleURL.net\/`grep -ril "example_needle" *`\/example\/path/g' `grep -ril "example_needle" *`
更新:
感谢您提供有用的答案。是的,我原来的单行中有一个错字:grep 的目标文件应该是 *.
我根据 Schewrn 的示例编写了一个小脚本,但结果令人困惑。这是我写的脚本:
#!/usr/bin/env perl -p -i
my $URL_First = "http://examplesite.net/some/path/";
my $URL_Last = "/example/example.xml";
my @files = `grep -ril $URL_Last .`;
chomp @files;
foreach my $val (@files) {
@dir_names = split('/',$val);
if(@dir_names[1] ne $0) {
my $url = $URL_First . @dir_names[1] . $URL_Last;
open INPUT, "+<$val" or die $!;
seek INPUT,0,0;
while(<INPUT>) {
$_ =~ s{\Q$URL_Last}{$url}g;
print INPUT $_;
}
close INPUT;
}
}
基本上我想做的是:
- 查找包含 $URL_Last 的文件。
- 将 $URL_Last 替换为 $URL_First 加上匹配文件所在目录的名称,再加上 $URL_Last。
- 将上述更改写入输入文件,而不修改输入文件中的任何其他内容。
运行我的脚本后,它完全混淆了输入文件中的 HTML 代码,并切断了文件中每一行的前几个字符。这很奇怪,因为我确定 $URL_Last 在每个文件中只出现一次,所以它应该只匹配一次并替换一次。这是因为seek函数的误用造成的吗?
【问题讨论】:
-
如果我没记错的话,
grep -ril "example_needle"缺少目标文件,因为您无法在标准输入上打印文件名。也许您应该尝试解释一下您要做什么。 -
花时间制作一个小样本文件,您可以将其编辑到您的问题中,并显示您需要的输出。否则,我们只是猜测。祝你好运。
-
Seek 绝对是不必要的,因为当您打开文件时,文件句柄位置已经在开头。至于你的问题描述,你会发现 1 个例子胜过 10 篇论文。例如,我假设您想要打开
foo/bar.html,将/example/example.xml替换为http://examplesite.net/some/path/foo/example/example.xml? -
好吧,既然你没有再澄清就消失了,我只是将你指向File::Find,它除了为你省去麻烦的反引号之外,还可以让你提取文件名和目录。
-
试试这个:codepad.org/BFpIwVtz
标签: perl bash command-line replace backticks