使用 sed 從一個檔案到另一個檔案替換字串時,“替換命令中的錯誤標誌:'{”

使用 sed 從一個檔案到另一個檔案替換字串時,“替換命令中的錯誤標誌:'{”

我正在嘗試用 File2 中的字串替換 File1 中找到的字串

文件1

<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/27&amp;EntityID=Ad12911&amp;imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2011/03/20&amp;EntityID=Ad13304&amp;imgExtension=" />
<IMG SRC="/Repository/GetImage.dll?baseHref=Orange/2010/08/29&amp;EntityID=Ad13724&amp;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 's/.SRC =“/儲存庫([^”])".*/\1/p' -e '{' -e 'r File1' -e 'd' -e '}' File2

但這不會達到你想要的效果。它從輸入中刪除前綴…SRC="Repository/和從下一個雙引號開始的部分,僅列印已替換的行(因為命令p上的標誌s以及以下),並為每個輸入行d插入一個副本File1

如果您想匹配兩個文件中的數據,您將需要一個比 sed 更強大的工具。awk或者珀爾都是不錯的選擇。

1從技術上講,sed 是圖靈完備的,但在 sed 中這樣做會非常複雜和晦澀。

相關內容