![使用 sed 从一个文件到另一个文件替换字符串时,“替换命令中的错误标志:'{”](https://linux22.com/image/57493/%E4%BD%BF%E7%94%A8%20sed%20%E4%BB%8E%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E5%88%B0%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E6%9B%BF%E6%8D%A2%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%97%B6%EF%BC%8C%E2%80%9C%E6%9B%BF%E6%8D%A2%E5%91%BD%E4%BB%A4%E4%B8%AD%E7%9A%84%E9%94%99%E8%AF%AF%E6%A0%87%E5%BF%97%EF%BC%9A'%7B%E2%80%9D.png)
我正在尝试用 File2 中的字符串替换 File1 中找到的字符串
文件1
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/27&EntityID=Ad12911&imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/20&EntityID=Ad13304&imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2010/08/29&EntityID=Ad13724&imgExtension=" />
文件2
/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif
/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif
/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif
当我运行这个命令时
$ sed -e 's/.*SRC="\/Repository\([^"]*\)".*/\1/p{r File1' -e 'd}' File2
我收到这个错误
sed: 1: "s/.*SRC="\/Repository\( ...": bad flag in substitute command: '{'
我的正则表达式有问题吗?
我试图实现的结果是让 File1 看起来像:
文件1
<IMG SRC="/Repository/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif" />
<IMG SRC="/Repository/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif" />
<IMG SRC="/Repository/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif" />
答案1
如果您尝试用File1
从那时起获取的新图像名称替换双引号内的所有内容,File2
我将使用 awk:
awk -F'"' 'NR==FNR{a[i++]=$1;next}{print $1 FS a[j++] FS $3}' File2 File1
输出如下:
<IMG SRC="/getimage.dll?path=Orange/2011/03/27/129/Img/Ad1291103.gif" />
<IMG SRC="/getimage.dll?path=Orange/2011/03/20/133/Img/Ad1330402.gif" />
<IMG SRC="/getimage.dll?path=Orange/2010/08/29/137/Img/Ad1372408.gif" />
答案2
我不知道你想在那里做什么,但我的 sed-fu 不是那么强,所以我猜你正在使用一些我不知道的神秘语法。由于我无法告诉您 sed 有什么问题(但有根据的猜测是替换字符串中包含的特殊字符(/
等?
)导致了问题),因此我将提供一个 perl 替代方案:
perl -i -pe 'BEGIN{open($f,shift); while(<$f>){chomp; push @F,$_}}
$k=shift(@F); s/(.*SRC=.)([^"]*)/$1$k/' file2 file1
这是作为注释脚本编写的相同内容,以使其更加清晰。在上面的一行中, 会-i
导致实际输入文件发生更改,就像sed -i
.
#!/usr/bin/env perl
## This is the equivalent of the BEGIN{} block.
## @ARGV is the array of arguments and shift returns
## the first element of it. This is file2 which is
## then opened, each line is read, its trailing \n
## is removed by chomp and it is then added to the @F array.
my $file=shift(@ARGV);
open($f,$file);
while(<$f>){chomp; push @F,$_}
## This is the rest of the oneliner above. The -pe options
## cause the file to be read and each line printed after
## the script is applied. Since the previous block removed
## file2 from @ARGV, this is applied to file1 only.
while (<>) {
## Remove the 1st item of @F. This is a line of file2.
$k=shift(@F);
## Make the substitution. The \ before the " is not
## needed, I just added it here because otherwise, the
## syntax highlighting is broken.
s/(.*SRC=.)([^\"]*)/$1$k/;
## This print is implied by the -p flag
print;
}
答案3
该错误告诉您您的 sed 命令错误,而不是您的正则表达式错误。您需要使用换行符或分号来将该s
命令与以下{
命令分隔开。同样,您可以将它们放在单独的-e
参数中。
sed -e 的/.SRC =“/存储库([^”])".*/\1/p' -e '{' -e 'r File1' -e 'd' -e '}' File2
但这不会达到你想要的效果。它从输入中删除前缀…SRC="Repository/
和从下一个双引号开始的部分,仅打印已替换的行(因为命令p
上的标志s
以及以下),并为每个输入行d
插入一个副本(匹配File1
或不)。
如果您想匹配两个文件中的数据,您将需要一个比 sed 更强大的工具。awk或者Perl都是不错的选择。
1从技术上讲,sed 是图灵完备的,但在 sed 中这样做会非常复杂和晦涩。