"대체 명령의 잘못된 플래그: '{" 문자열을 한 파일에서 다른 파일로 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에 무엇이 문제인지 말할 수 없기 때문에(그러나 교육받은 추측에 따르면 대체 문자열( 등)에 포함된 특수 문자가 /문제 ?를 일으키는 것으로 추측됩니다) 대신 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 파일1' -e 'd' -e '}' 파일2

하지만 이것은 당신이 원하는 대로 되지 않을 것입니다. 입력에서 접두어와 다음 큰따옴표로 시작하는 부분을 제거하고 (명령 의 플래그 와 다음 …SRC="Repository/으로 인해) 대체된 행만 인쇄하며 , 각 입력 행에 대해 (일치하는) 사본을 삽입합니다 . 아니면 아닙니다).psdFile1

두 파일의 데이터를 일치시키려면 sed¹보다 더 강력한 도구가 필요합니다.또는좋은 선택입니다.

¹ 기술적으로 sed는 Turing 완전체이지만 sed에서 이를 수행하는 것은 매우 복잡하고 모호합니다.

관련 정보