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
“포인터”를 포함하는 줄 앞에.
답변
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
답변
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
있지만,보다 명확하게 수 sed
의 awk
솔루션입니다.
답변
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
답변
쉬운 직업 ed
:
ed -s file1 <<IN
/Pointer/-r file2
,p
q
IN
-r file1
지정된 파일에서 지정된 행 다음으로 읽습니다.이 경우 첫 번째 행이 일치하는 이전 행 Pointer
입니다. 따라서 여러 줄에서 발생 file2
하더라도 내용을 한 번만 삽입합니다 Pointer
. 일치하는 각 줄 앞에 g
lobal 플래그를 추가하려면 다음을 입력하십시오 .
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
일치하는 각 줄 앞에 내용 을 삽입 합니다. 첫 번째 일치하는 줄 l
앞에만 삽입하려면 oop를 사용하고 n
파일 끝이 나올 때까지 ext 행을 당기십시오 .
sed '/Pointer/{
r file2
N
:l
$!n
$!bl
}
${
/^$/!{
s/\n$//
}
//d
}' file1 <(printf %s\\n)
이러한 sed
솔루션을 사용하면 내부 편집 기능이 손실되지만 다른 파일로 리디렉션 할 수 있습니다.
답변
루프를 사용하여 file2의 행을 읽으십시오. 로 시작하는 줄을 찾으면 Pointer
file1을 인쇄하십시오. 이것은 아래와 같습니다 :
#!/bin/bash
while IFS= read -r line
do
if [[ "$line" =~ ^Pointer.*$ ]]
then
cat file1
fi
echo "$line"
done < file2
답변
이 문제를 해결하는 몇 가지 방법이 sed
있습니다. 한 가지 방법은 승인 된 답변에 권장되는 지연된 읽기입니다. 다음과 같이 쓸 수도 있습니다 :
sed -e '$!N;P;/\nPointer/r file1' -e D file2
… 보류 버퍼로 다른 곳에서 구현 된 룩-비어 대신에 약간의 명시 적 룩-어 헤드가 있습니다. 그러나 줄 간격을 늘리고 ead 명령을 줄 번호로 적용 하기 때문에 @don_crissti가 마지막 줄에 문제 N
가 있습니다 r
.
당신은 그것을 둘러 볼 수 있습니다 :
echo | sed -e '$d;N;P;/\nPointer/r file1' -e D file2 -
모든 것이 표준 입력을 의미하는 sed
것으로 해석 -
하지는 않지만 많은 사람들이 표준 입력을 의미합니다. ( POSIX는 구현자가 표준 입력을 원한다면 표준 입력을 sed
지원해야 한다고 말합니다. ?? )-
-
다른 방법은 추가 된 내용을 순서대로 처리하는 것입니다. ead 와 동일한 방식으로 출력 을 예약 하는 다른 명령 이 있으며 스크립트 및 스크립트 순서대로 적용합니다 . 이 하나를 사용 수반 – 그것은하지만 좀 더 참여의 할 ppend 다른 사람의 출력에 일치 의 스크립트를.r
sed
r
sed
a
Pointer
sed
sed ' /Pointer/!d #only operate on first match
s/[]^$&\./*[]/\\&/g;H #escape all metachars, Hold
s|.*|/&/!p;//!d|p;g #print commands, exchange
s|.|r file1&a\\&|;q' file2| #more commands, quit
sed -nf - file2 #same input file
기본적으로 첫 번째 sed
는 두 번째 sed
스크립트를 작성하는데, 두 번째 스크립트 sed
는 표준 입력 (아마도 …)을 읽고 차례로 적용합니다. 첫 번째 sed
는 Pointer
찾은 이후의 q
uits 입력 에 대한 첫 번째 일치에서만 작동 합니다. 그 임무는 …
s/[]^$&\./*[]/\\&/g;H
- 모든 패턴 문자는 백 슬래시로 이스케이프 처리해야합니다. 두 번째 문자는
sed
문자를 올바르게 읽을 수 있도록 모든 비트를 해석해야하기 때문입니다. 완료되면H
오래된 공간에 사본을 넣으십시오 .
- 모든 패턴 문자는 백 슬래시로 이스케이프 처리해야합니다. 두 번째 문자는
s|.*|/&/!p;//!d|p; x
- 두 번째
sed
는p
모든 입력 라인 을 찢으 라고!
말하지만/&/
방금 패턴으로 보호 된 라인을 말하십시오 . 그리고d
똑같은 것을 피하기 위해 .p
두 번째에 명령을 찢은sed
다음, 저장된 사본에서 작동x
하도록h
이전 및 패턴 버퍼를 변경하십시오 .
- 두 번째
s|.|r file1&a\\&|p;q
- 유일한 우리가 여기에서 작동 숯불 것은입니다
\n
ewline 때문에sed
우리가 하나 앞에 추가 한 것입니다H
전에 선을 ELD을. 그래서 우리는 명령을 삽입r file1
하고\n
ewline 다음a\\
에a
ppend 명령 과 ewline을 차례로\n
따릅니다. 나머지H
필드는 마지막 줄을 따릅니다\n
.
- 유일한 우리가 여기에서 작동 숯불 것은입니다
처음 쓰는 스크립트는 다음과 같습니다.
/Pointer-file2 "23"/!p;//!d
r file1
a\
Pointer-file2 "23"
기본적으로 두 번째 sed
는 모든 줄을 인쇄하지만 첫 번째 줄 sed
은 a
보류 하도록 설정합니다 . 이 특정 라인의 경우 표준 출력에 대한 지연된 쓰기 2 개가 예약됩니다 . 첫 번째는 r
ead file1
이고 두 번째는 원하는 라인의 사본입니다. 이 경우 첫 번째 sed
닥터 링은 필요 하지 않지만 (백 슬래시 없음 참조) 패턴 일치가 입력으로 용도 변경 될 때마다 내가 여기서하는 방식으로 안전하게 탈출하는 것이 중요합니다.
어쨌든 몇 가지 방법이 있습니다.
답변
이것은 AWK에서 매우 간단합니다.
패턴 = “포인터”전에 File1을 File2로
먼저 File1의 내용을 변수에로드하십시오.
f1="$(<File1)"
그런 다음 삽입
awk -vf1="$f1" '/Pointer/{print f1;print;next}1' file2
(또는 “포인터”뒤에 File1을 삽입하려는 경우)
awk -vf1="$f1" '/Pointer/{print;print f1;next}1' file2