여러 파일이 포함된 폴더가 있습니다. .txt
이 파일의 내용을 기반으로 세 개의 새 파일을 만들고 싶습니다 . 이를 달성하기 위해 3개의 새 문서를 만드는 데 사용할 파일의 다른 부분을 표시하는 begin
/ 태그를 만들어야 한다고 생각했습니다 .end
예를 들어 첫 번째 파일의 구조 01_FileName.mac
는 다음과 같습니다.
/* 01_FileName */
/* START HEADER */
Header 1 Content
/* END HEADER */
/* START SCRIPT */
Script 1 Content
/* END SCRIPT */
/* START COMMENTS */
Comments 1 Content
/* END COMMENTS */
마찬가지로 두 번째 입력 파일은 다음과 같습니다 02_FileName.mac
.
/* 02_FileName */
/* START HEADER */
Header 2 Content
/* END HEADER */
/* START SCRIPT */
Script 2 Content
/* END SCRIPT */
/* START COMMENTS */
Comments 2 Content
/* END COMMENTS */
해당 파일이 2개 이상 있다는 점에 유의하세요.
다음 세 가지 새 문서를 만들고 싶습니다.
Concatenated_Header.txt
:Header 1 Content Header 2 Content
Concatenated_Script.txt
:Script 1 Content Script 2 Content
Concatenated_Load_Commands.txt
:push("<NameOfCurrentPath>")$ load("<NameOfCurrentPath>/01_FileName.mac")$ load("<NameOfCurrentPath>/02_FileName.mac")$
특정 줄이나 특정 문자열을 연결하는 것과 관련된 예제를 본 적이 있지만, 부분을 새로운 개별 파일로 결합하기 위해 start
나누고 합하는 일반적인 방법은 아닙니다.end
참고: 파일의 정확한 구조는 실제로 중요하지 않습니다. 이러한 부분( , 및 )을 내보내는 데 도움이 되는 문서 fileName
구조 는 괜찮습니다 . 목표는 스크립트와 관련된 모든 정보를 단일 파일에 저장하면서 이 세 개의 새 파일을 생성하는 것입니다. 이것이 바로 제가 라벨을 사용하여 이 프로세스를 용이하게 할 수 있다고 상상한 방식입니다.Header Content
Script Content
Comments Content
start
end
(이것을 봐주세요초기 개정더 많은 배경과 세부사항을 보려면)
답변1
awk 'function prnt(type, pr){ print pr >"concatenated_"type".txt"; };
FNR==1{ type="load";
if (!path) {
path=FILENAME; sub("[^/]+$","",path);
prnt(type, "push(\"<"path">\")$");
};
prnt(type,"\tload(\"<"FILENAME">\")$");
};
/START HEADER/{ prn=1; type="header"; next; };
/START SCRIPT/{ prn=1; type="script"; next; };
/END SCRIPT/ || /END HEADER/{ prn=0; };
prn{ prnt(type, $0); }' /home/User/Unix/*.mac
우리는앗Function; prnt
은 이름이며 두 개의 인수를 사용합니다. 하나는 짧은 문자열을 가져와 pr
인수의 출처에서 줄을 작성해야 하는 출력 파일 이름의 일부로 사용합니다.
function prnt(type, pr){ print pr >"concatenated_"type".txt"; }
매개변수 type
값은 조건부로 변경되는데, input 의 첫 번째 줄이면 파일 이름과 경로를 기록하도록 FNR==1
설정 하지만type="load"
길if(!path) { path=FILENAME; ...; }
한 번만 작성해야 하므로 한 번만 작성되도록 했습니다 . 다음 번에는 path
변수에 이미 값이 있으므로 if 문의 블록이 실행되지 않습니다.길다시 분리됨) 나머지 입력에서는 파일 이름과 각 파일을 FNR==1
.
행에 가 포함되어 있는지 설정 /START HEADER/
하고 그에 따라 ; type="header"
또한 제어 변수 플래그를 사용하여 개인 파일 이름에 줄을 인쇄하기 위해 함수가 호출되는 시기를 제어합니다.type="script"
/START SCRIPT/
prn=1
prn{ prnt(type, $0); }
next
명령은 다시 시작하고 입력의 다음 줄을 읽는 데 사용되므로 다음 명령을 계속하거나 쓰지 않습니다.타이틀 출발선출력의 라인 자체.
또한 prn=0
인쇄를 방지하기 위해 플래그를 재설정합니다.머리부터 꼬리까지철사.
답변2
$ cat tst.awk
BEGIN {
out["HEADER"] = "Concatenated_Header.txt"
out["SCRIPT"] = "Concatenated_Script.txt"
out["LOAD"] = "Concatenated_Load_Commands.txt"
}
FNR == 1 {
if ( NR == 1 ) {
dir = FILENAME
sub("/[^/]+$","",dir)
printf "push(\"%s\")$\n", dir > out["LOAD"]
}
printf " load(\"%s\")$\n", FILENAME > out["LOAD"]
}
block {
if ( index($0,"/* END ") == 1 ) {
block=""
}
if ( block in out ) {
print > out[block]
}
next
}
index($0,"/* START ") == 1 { block=$3; next }
$ awk -f tst.awk $PWD/*.mac
$ head Concat*
==> Concatenated_Header.txt <==
Header 1 Content
Header 2 Content
==> Concatenated_Load_Commands.txt <==
push("/home/foo/tmp")$
load("/home/foo/tmp/01_FileName.mac")$
load("/home/foo/tmp/02_FileName.mac")$
==> Concatenated_Script.txt <==
Script 1 Content
Script 2 Content
out["COMMENTS"] = "Concatenated_Comments.txt"
주석의 출력 파일도 생성하려면 해당 섹션에 한 줄을 추가하면 됩니다 BEGIN
. 귀하가 만드는 다른 콘텐츠도 마찬가지입니다 START
. .. END
조각 . 스크립트는 /* START
블록의 외부와 내부 만 검색하며 /* END
둘 다 줄의 시작 부분에서만 검색하므로 이러한 문자열은 스크립트를 손상시키지 않고 텍스트 블록에 나타날 수 있습니다.