다른 여러 줄 텍스트 파일 내에서 여러 줄 텍스트 파일 하나를 찾아 바꾸기

다른 여러 줄 텍스트 파일 내에서 여러 줄 텍스트 파일 하나를 찾아 바꾸기

나는 오랫동안 그 문제로 어려움을 겪었지만 지금은 완전히 아이디어가 없습니다. 어쩌면 여기 누군가가 나를 도와줄 수도 있어요. 이것이 내가 달성하고 싶은 것입니다:

file_1.txt:

# Some comment
some_variable="test"
some other things

# Marker

More things!@#$%^

file_2.txt:

# Marker
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"

대신 file_2.txt에 삽입 하고 나중에 프로세스를 되돌리고 싶습니다.file_1.txt# Marker

최종 문서 file_1.txt:

# Some comment
some_variable="test"
some other things

# Marker
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"

More things!@#$%^

문제는 두 파일 모두 여러 줄로 되어 있고 다양한 특수 문자가 포함되어 있다는 것입니다. 또한 이 두 파일을 변수에 넣고 싶습니다.

나는 sed, Perl, awk 등 다양한 것을 시도했습니다. 나에게는 아무것도 효과가 없습니다. 나는 이것이 나의 가장 가까운 시도라고 생각합니다.

perl -pi -e 'chomp if eof' file_2.txt
marker_var="# Marker"
file_2_var=$(tr '\n' '\f' <file_2.txt)

sed -e "s|$marker_var|$file_2_var| tr '\f' '\n'" file_1.txt

아직 작동하지 않기 때문에 가장 가깝다고 말합니다. stackexchange의 다양한 답변을 결합해 보았지만 제대로 끝나지 않는다는 오류가 발생합니다 s. 파일의 마지막 새 줄 때문인 것으로 의심되어 \nperl 명령을 사용하여 제거하려고 시도했지만 작동하지 않았습니다.

누구든지 나를 도와줄 수 있나요?

답변1

이미 Perl이 있다면 Perl을 실행하십시오:

open(f1,"<file_1.txt");
open(f2,"<file_2.txt");
open(out,">new_file_1.txt");

while(<f1>) {
   last if /# Marker/;
   print out;
}
print out while(<f2>);
print out while(<f1>);

close(out);
close(f1);
close(f2);

답변2

awk를 사용하여 파일을 병합하는 것은 실제로 매우 간단합니다.

awk 'NR==FNR {if ($1 == "#" && $2 == "Marker") while((getline a<ARGV[2]) > 0) print a; else print}' file_1.txt file_2.txt > out
  • NR==FNR이것은 첫 번째 파일에서만 작동하도록 하는 이상한 트릭입니다. 이것을 확인하세요더 많은 정보를 원하시면 답변해주세요NR 및 FNR 정보
  • {if ($1 == "#" && $2 == "Marker")else print}# Marker: 첫 번째 파일을 구문 분석하고 모든 줄을 출력합니다.아니요확립된.
  • while((getline a<ARGV[2]) > 0) print a;ARGV[2](여기서는 file_2.txt)의 내용을 구문 분석하여 출력합니다.
  • > out셸 리디렉션이며 이 명령의 출력을 out 파일에 기록합니다(파일이 없으면 파일 생성).

결과:

$ awk 'NR==FNR {if ($1 == "#" && $2 == "Marker") while((getline a<ARGV[2]) > 0) print a; else print}' file_1.txt file_2.txt
# Some comment
some_variable="test"
some other things

# Marker
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"

More things!@#$%^

답변3

사용sed

$ sed -Ee '/Marker/{e cat file_2.txt' -e ';d}' file_1.txt
# Some comment
some_variable="test"
some other things

# Marker
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"


More things!@#$%^

답변4

awk를 사용하십시오.

$ awk 'NR==FNR{new=new sep $0; sep=ORS; next} /# Marker/{$0=new} 1' file_2.txt file_1.txt
# Some comment
some_variable="test"
some other things

# Marker
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"

More things!@#$%^

$ awk 'NR==FNR{new=new sep $0; sep=ORS; next} /# Marker/{$0=new} 1' file_1.txt file_2.txt
# Some comment
some_variable="test"
some other things

# Marker

More things!@#$%^
# Some other comment
other_variable_1="test"

# Some totally other comment
other_variable_2="test"

귀하의 질문에 있는 스크립트와 관련하여:

  1. 이 작업을 수행하면 tr '\n' '\f'더 이상 필요한 종료 개행 문자가 포함되어 있지 않으므로 더 이상 유효한 텍스트 파일이 없으므로 YMMV sed또는 기타 텍스트 처리 도구가 이를 처리합니다.
  2. 입력에 폼 피드가 포함되어 있으면 줄바꿈을 폼 피드에 매핑하는 프로세스가 실패합니다. 이는 인쇄(또는 기타 유사한 텍스트) 시 새 페이지의 상단에서 함수가 시작되도록 강제하려는 코드의 함수 사이에 사용되는 것과 같습니다. 인쇄할 때 특정 위치에 페이지가 표시됩니다.)
  3. sed -e "s|$marker_var|$file_2_var|자체적 으로 s 또는 역참조가 file_2_var포함될 수 있으므로 이 작업을 수행할 수 없습니다 |. 예를 들어 &sed가 \1이를 해석합니다.https://stackoverflow.com/q/29613304/1745001.

관련 정보