複数のファイルを含むフォルダがあります。.txt
このファイルの内容に基づいて3つの新しいファイルを作成したいと思います。これを達成するために、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 */
同様に、2番目の入力ファイルは次のとおりです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つ以上あることに注意してください。
次の3つの新しい文書を作成したいと思います。
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
構造は問題ありません。目的は、スクリプトに関するすべての情報を単一のファイルに保存しながら、これら3つの新しいファイルを作成することです。これが私がラベルを使ってこのプロセスを容易にすることができると想像した方法です。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
は名前で、2つの引数を使用します。 1つは、短い文字列を取得し、引数のソース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"
コメントの出力ファイルも作成するには、そのセクションに1行を追加するだけですBEGIN
。あなたが作る他のコンテンツも同じですSTART
。 ..END
彫刻 。スクリプトは/* START
ブロックの外側と内側のみを検索し、両方とも行/* END
の先頭でのみ検索するため、これらの文字列はスクリプトを破損することなくテキストブロックに表示される可能性があります。