다른 파일의 패턴(태그) 앞에 한 파일의 내용을 삽입하는 방법은 무엇입니까?

다른 파일의 패턴(태그) 앞에 한 파일의 내용을 삽입하는 방법은 무엇입니까?

File1콘텐츠:

line1-file1      "1" 
line2-file1      "2"
line3-file1      "3" 
line4-file1      "4" 

File2콘텐츠:

line1-file2     "25"  
line2-file2     "24"  
Pointer-file2   "23"  
line4-file2     "22" 
line5-file2     "21"

Perl/shell 스크립트가 실행된 후 File2내용은 다음과 같아야 합니다.

line1-file2     "25"  
line2-file2     "24" 
line1-file1      "1" 
line2-file1      "2"
line3-file1      "3" 
line4-file1      "4" 
Pointer-file2   "23" 
line4-file2     "22" 
line5-file2     "21"

File1즉, File2"Pointer"가 포함된 줄 앞에 in의 내용을 붙여넣습니다.

답변1

sed유틸리티에는 수정 작업을 수행하는 기능이 있습니다.

sed -i -e '/Pointer/r file1' file2

하지만 이것이 당신을바늘콘텐츠 위의 행입니다 file1. 간단히 말해서 지연 라인 출력입니다.

sed -n -i -e '/Pointer/r file1' -e 1x -e '2,${x;p}' -e '${x;p}' file2 

GNU 사용 sed:

sed '/Pointer/e cat file1' file2

~에 따르면수동을 위한 e [command]:

r 명령과 달리 이 명령의 출력은 즉시 인쇄됩니다. r 명령은 현재 기간이 끝날 때까지 출력을 지연합니다.

답변2

sed또는 를 사용하지 마십시오 awk.

먼저 패턴이 있는 행을 찾으세요.

line=$(grep -n 'Pointer' file2 | cut -d ":" -f 1)

그런 다음 3개의 명령을 사용하여 원하는 결과를 출력합니다.

{ head -n $(($line-1)) file2; cat file1; tail -n +$line file2; } > new_file

이는 3번 방문해야 한다는 단점이 있지만 의 솔루션 file2보다 더 깔끔할 것입니다 .sedawk

답변3

awk이것을 꽤 쉽게 만듭니다.
파일 앞에 다음 줄을 삽입합니다.

awk '/Pointer/{while(getline line<"innerfile"){print line}} //' outerfile >tmp
mv tmp outerfile

해당 줄 다음에 내부 파일을 인쇄하려면 Pointer모드 순서를 전환하고(기본 동작을 얻으려면 세미콜론을 추가해야 함) 변수를 제거할 수 있습니다 line.

awk '//; /Pointer/{while(getline<"innerfile"){print}}' outerfile >tmp
mv tmp outerfile

아직 아무도 사용하지 않았기 때문에 perl,

# insert file before line
perl -e 'while(<>){if($_=~/Pointer/){system("cat innerfile")};print}' outerfile

# after line
perl -e 'while(<>){print;if($_=~/Pointer/){system("cat innerfile")}}' outerfile

답변4

간단한 작업 ed:

ed -s file1 <<IN
/Pointer/-r file2
,p
q
IN

-r file1지정된 파일을 지정된 라인으로 읽은 후, 이 경우 첫 번째 라인 이전의 라인이 일치합니다 Pointer. 따라서 여러 줄에 나타나 file2더라도 내용은 한 번만 삽입됩니다. Pointer일치하는 각 행 앞에 삽입하려면 g전역 플래그를 추가하세요.

ed -s file1 <<IN
g/Pointer/-r file2
,p
q
IN

파일을 그 자리에서 편집하려면 ,p로 바꾸십시오.w


허용된 sed답변은 대부분의 경우 작동하지만 마커가 마지막 줄에 있으면 명령이 예상대로 작동하지 않습니다. 즉, File1마커 뒤에 내용이 삽입됩니다.
나는 처음에 다음을 시도했습니다.

sed '/Pointer/{r file1
N}' file2

또한 잘 작동하지만( r루프 끝에서 마법이 작동하는 것처럼) N마커가 마지막 행에 있는 경우(마지막 행 뒤에 분기가 없는 경우) 동일한 문제가 발생합니다. 이 문제를 해결하려면 입력에 개행 문자를 추가하면 됩니다.

sed '/Pointer/{              # like the first one, but this time even if the
r file1                      # marker is on the last line in File2 it
N                            # will be on the second to last line in
}                            # the combined input so N will always work;
${                           # on the last line of input: if the line is
/^$/!{                       # not empty, it means the marker was on the last
s/\n$//                      # line in File2 so the final empty line in the
}                            # input was pulled i\n: remove the latter;
//d                          # if the line is empty, delete it
}' file2 <(printf %s\\n)

file2일치하는 각 행 앞에 내용이 삽입 됩니다 . 일치하는 첫 번째 줄 앞에만 삽입하려면 oop를 사용하여 파일 끝에 도달할 때까지 다음 줄을 l당깁니다 .n

sed '/Pointer/{
r file2
N
:l
$!n
$!bl
}
${
/^$/!{
s/\n$//
}
//d
}' file1 <(printf %s\\n)

이러한 sed솔루션을 사용하면 제자리에서 편집하는 기능을 잃게 됩니다(그러나 다른 파일로 리디렉션할 수는 있음).

관련 정보