列(ヘッダーを含む)に基づいてファイルを分割して結果ファイルの名前を変更するにはどうすればよいですか?

列(ヘッダーを含む)に基づいてファイルを分割して結果ファイルの名前を変更するにはどうすればよいですか?

次の例があります.txt

NAME | CODE
name1 | 001
name2 | 001
name3 | 002
name4 | 003
name5 | 003
name6 | 003

このファイルを列に基づいて分割するスクリプトを作成する必要があるため、CODEこの場合は次のような結果が得られます。

file 1:
NAME | CODE
name1 | 001
name2 | 001

file 2:
NAME | CODE
name3 | 002

file 3:
NAME | CODE
name4 | 003
name5 | 003
name6 | 003

いくつかの研究では、awkを使用すると、次のことができます。

$ awk -F, '{print > $2".txt"}' inputfile

問題は、最初の行にタイトルも含める必要があり、ファイル名も異なる必要があることです。たとえば001.txt、必要なファイル名ではありませんFILE_$FILENAME_IDK.txt

答え1

次のことを試すことができます。

awk 'NR==1{h=$0; next}
!seen[$3]++{f="FILE_"FILENAME"_"$3".txt";print h > f} 
{print >> f}' infile

上記はヘッダーを変数h()に保存し、表示されないNR==1{h=$0; next}場合(つまり最初に発生した場合)に現在の値を設定します。$3!seen[$3]++$3ファイル名f=...)そしてタイトルを書いてくださいファイル名print h > f)。その後、行全体をファイル名print >> f)。デフォルト値FS(フィールド区切り記号)を使用します。スペース|as FS(またはで正規表現gnu awk)を使用するには、以下を参照してください。カス'以下にコメントしてください。

答え2

誰かが気の利いたことを言うかもしれませんが、私はスクリプトを書く必要があります。

in='inputfile'
header=$(head -n1 "$in")
codes=($(sed -n 's/.*| \([0-9]\+\)/\1/p' "$in" | uniq ))
for line in "${codes[@]}"; do
    out="file_$i.txt"
    echo "$header" > "$out"
    grep "|.* $line$" "$in" >> "$out"
done

関連情報