"置換コマンドの無効なフラグ: '{" sedを使用してあるファイルから別のファイルに文字列を置き換えるとき

"置換コマンドの無効なフラグ: '{" sedを使用してあるファイルから別のファイルに文字列を置き換えるとき

File1の文字列をFile2の文字列に置き換えようとしています。

ファイル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二重引用符内のすべての内容をそれから取得した新しいイメージ名に置き換えるには、File2awkを使用します。

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に問題があるかどうかはわかりません(しかし、訓練された推測によると、代替文字列に含まれる特殊文字(/etc. ?)が問題を引き起こすと推測されます)、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 ファイル1' -e 'd' -e '}' ファイル2

しかし、これはあなたが望む効果を得ることはできません。 input で接頭辞と次の二重引用符で始まる部分を削除し…SRC="Repository/、置換された行だけを印刷し(コマンドと下のpフラグのためs)、d各入力行のコピーを挿入します(一致するFile1かどうか)。

両方のファイルのデータを一致させるには、sedよりも強力なツールが必要です。アッまたはパールすべて良い選択です。

1技術的にsedはTuring完全ですが、sedでそれを行うのは非常に複雑であいまいです。

関連情報