sed를 사용하여 파일 내용을 가져와 일치하는 패턴 뒤에 다른 파일에 삽입하려고 합니다. 내 문제는 다음과 매우 유사합니다.이 문제, 하지만 파일 내용을 새 줄이 아닌 인라인으로 삽입하고 싶습니다. 어떻게 해야 하나요?
내가 인용한 예제 질문을 사용하면 첫 번째 대답은 내가 원하는 것을 정확히 수행하지만 삽입이 인라인으로 발생하기를 원합니다.
sed '/First/r file1.txt' infile.txt
삽입하려는 실제 데이터는 JSON 파일입니다.
[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
]
답변1
당신이 링크한 질문에는 이미 좋은 대답이 있습니다 . 개행 없이 삽입하는 대신 awk
다음을 사용하여 약간 수정하십시오 .printf
print
awk '/First/ { printf $0; getline < "File1.txt" }1' infile.txt
결과:
Some Text here
FirstThis is text to be inserted into the File.
Second
Some Text here
"첫 번째" 뒤에 공백이나 기타 구분 기호를 추가해야 할 수도 있습니다.printf $0 " "; ...
삽입된 파일에 여러 줄이 있는 경우 다음을 수행합니다.
awk '/First/{printf $0; while(getline line<"File1.txt"){print line};next}1' infile.txt
결과:
Some Text here
First[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
]
Second
Some Text here
답변2
다음을 사용할 수 있습니다 perl
(파일 내용을 가져와 + pattern
로 바꾸기 ).pattern
file content
perl -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/' file.txt
-i
PAT(패턴)가 발생할 때마다 내부 편집을 추가합니다 . g
예:
perl -i -pe '$text=`cat insert.txt`; chomp($text); s/PAT/$&$text/g' file.txt
또 다른 방법은 다음을 사용하십시오 ed
.
printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j ,p q | ed -s file.txt
그 자리에서 편집하려면 다음 ,p
으로 바꾸세요 w
.
printf '%s\n' /PAT/s/PAT/\&\\ \/ - kb ". r insert.txt" j \'b j w q | ed -s file.txt
아마도 아무도 이것이 어떻게 작동하는지 관심이 없을 것입니다. 그러나 어쨌든 printf
명령 목록을 다음으로 전달하십시오 ed
.
/PAT/s/PAT/&\ # set address to first line matching PAT and
/ # split the line right after PAT
- # set address one line before (return to the line matching PAT)
kb # mark the current line
. r insert.txt # insert content of insert.txt after this line
j # join current line and the next
'b # set address to marked line (return to the line matching PAT)
j # join current line and the next one
,p # print file content
q # quit editor
또는 printf
및를 사용하지 않고 다음을 수행합니다 |
.
ed -s file.txt <<< $'/PAT/s/PAT/&\\\n/\n-\nkb\n. r insert.txt\nj\n\'b\nj\nw\nq\n'
답변3
따라서 이 작업을 이식 가능하게 만드는 것은 약간 까다롭습니다 . 해당 컨텍스트에서 스크립트를 생성하려면 정규 표현식 전구체를 찾 거나 사용해야 sed
합니다 . 이는 항상 ewline이 삽입 되기 때문입니다.cut
paste
sed
\n
앞으로ead의 출력 r
. 그래도 GNU를 사용하면 다음과 같습니다 sed
.
sed '/First/{x;s/.*/cat file/e;H;x;s/\n//}' <<\IN
First
Second
Third
IN
e
이 작업은 귀하의 주소가 나타날 때마다 수행됩니다 . 이 작업은 기존 공간에서 수행됩니다.cat
/First/
h
(어쨌든 - 백업 버퍼 - 변경한 이후 실제로 는 이전 공간이었던 패턴 공간 x
에서 발생했습니다 .)h
행이 일치하는 것을 유지하려면 출력을 행에 추가하고 중간에 있는 ewline을 제거 First
하십시오 .cat
\n
산출:
First[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
]
Second
Third
이제 파일의 전체 내용을 맞추려면~ 사이위의 명령을 사용하여 줄 사이의 후행 개행 문자를 제거하기 때문에 줄의 두 부분은 약간 다르게 작동해야 합니다.끝줄의 위치와 파일의 시작 부분을 일치시킵니다. 그러나 다음과 같이 할 수도 있습니다.
sed '/First/{s//&\n/;h
s/.*/{ cat file; echo .; }/e;G
s/\(.*\).\n\(.*\)\n/\2\1/
}' <<\IN
Third
Second
First Second Third
Third
Second
First Second Third
IN
이것은 match에서 ewline 문자로 행을 분할 하고 이를 이전 공간 \n
에 저장하고 xecutes (패턴 공간을 해당 출력으로 대체)는 예약된 공간의 내용을 다른 ewline 문자 뒤의 새 패턴 공간에 추가한 다음 재정렬합니다 . 선 분리 기호.h
e
cat
G
\n
\n
나는 echo .
모든 후행 \n
Ewline 문자를 유지했습니다 file
. 하지만 그것이 당신의 바람이 아닐 경우(어쨌든 귀하의 예와는 관련이 없습니다)그것 없이도 할 수 있으며 아래 교체에서 .
앞에 있는 첫 번째 것을 제거할 수 있습니다..\n
s///
패턴 공간이 재배열되기 전의 모습은 다음과 같습니다.
^cat's output - any number of newlines.*.\nmatch on First\nrest of match$
산출:
Third
Second
First[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
] Second Third
Third
Second
First[
{
"foo": "bar",
"baz": "biff",
"data": [
{
"a": 1945619,
"b": [
{
"c": 512665,
"d": "futz"
}
]
}
]
}
] Second Third