2つの列を持つtest1.csvファイルがあります。
group,email
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
私の目標は、最初の列の値に基づいて別々のテキストファイルを作成することです。
たとえば、
最初のファイル名は[Eメール保護]そして包含
[email protected]
[email protected]
[email protected]
[email protected]
最初のファイル名は[Eメール保護]そして包含
[email protected]
[email protected]
など。
このawkコマンドがあります
awk -F"," 'NR==1{header=$0}NR>2&&!a[$1]++{print header > (""$1"")}NR>2{print > (""$1"")}' test1.csv
しかし、ファイル名が正しく指定されているにもかかわらず、結果は私が本当に望むものではありません。
group,email
[email protected],[email protected]
[email protected],[email protected]
[email protected],[email protected]
さらに、.csvファイルが大きすぎるたびに、「Awk:開いたファイルが多すぎます」というメッセージが表示されます。
助けてくれてありがとう。また、sedやgrepなどの他の言語も見てください。
答え1
これがあなたに必要なものです:
awk -F ',' 'NR<2{next} p1!=$1&&p1{close(p1)} {p1=$1;print $2>p1}' file
NR<2{next}
:タイトルをスキップします。p1!=$1&&p1{close(p1)}
:p1
前の行の最初のフィールド()が現在の行の最初のフィールドと異なる場合は、「あまりにも開いているファイル」が発生しないように、古い出力ファイルが閉じられます(まだ開かれていない限り)。そして開くp1
)。未設定)。{p1=$1;print $2>p1}
:最初のフィールドをp1
変数に入れ、2番目のフィールドを最初のフィールド名のファイルに出力します。
file
上記のawkでは、提供された例に示されているように、最初のフィールドは同じ行が一緒にグループ化されていると想定しています。そうでない場合、簡単な解決策はawkにソートされた入力を提供し、ヘッダーを明示的にスキップすることです(ヘッダーが最初の行にないため)。
sort file | awk -F ',' '/^group,email$/{next} p1!=$1&&p1{close(p1)} {p1=$1;print $2>p1}'
答え2
awk
指定されたファイル名に直接リダイレクトできます(ドメイン名はスペースに安全でなければなりません)。$2
$1
awk -F, 'NR>1{print $2 > $1}' file
ヘッダーをスキップしてファイルを開いたままにします。ヘッダー++h[$1]==1
を書き込む新しいファイルかどうかをテストし、次を使用して追加することでこの問題を解決できます。>
>>
$2
close($1)
awk -F, '
NR==1{header=$0}
NR>1{
if(++h[$1]==1)print header > $1;
print $2 >> $1; close ($1)
}' file
重複を避けるために、++f[$0]==1
添付する前にテストしてください。
awk -F, '
NR==1{header=$0}
NR>1&&++f[$0]==1{
if(++h[$1]==1)print header > $1;
print $2 >> $1; close ($1)
}' file
head *.com
==> [email protected] <==
group,email
[email protected]
[email protected]
[email protected]
[email protected]
==> [email protected] <==
group,email
[email protected]
[email protected]
==> [email protected] <==
group,email
[email protected]
[email protected]
[email protected]
ファイルが完全にまたは部分的にソートされている場合は、次のように各行を盲目的に開閉することを防ぎます。
awk -F, '
NR==1{header=$0}
NR>1&&++f[$0]==1{
if ($1 != old) close(old);
if(++h[$1]==1)print header > $1;
print $2 >> $1; old=$1
}' file
これはデータファイルを使用しているため、$2 >>
2番目のブロックがあっても問題はなく、$1
新しいブロックによって削除されません。>
答え3
ミラーの使用(https://github.com/johnkerl/miller)簡単に言うと
mlr --csv put -q 'tee > $group, $*' ./input.csv
mlr -I --c2n cut -f email ./group*@*
これは奇妙なことではありませんが、あなたに効果があると思いました。
答え4
$ awk '{print (NR>1),$0}' file | sort -k1,1n -k2 | cut -d' ' -f2- |
awk -F, '
NR==1 { hdr=$0; next }
$1 != out { close(out); out=$1; print hdr > out }
{ print $2 " > " out }
'
上記のコードは、ほぼすべてのサイズの入力ファイルのすべてのawkで動作し、入力行の順序は関係なく高速です。
テスト完了後、実際に出力ファイルを生成するprint $2 " > " out
ように変更されました。print $2 > out