大容量ファイルから列を抽出して新しいファイルに貼り付けて、データファイルを準備しようとしています。
そのデータの列数が非常に多いです。データを分割して複数のデータファイルを準備したいと思います。
以下のスクリプトを試していますが、動作しません。コピーする列の範囲を指定すると、エラーが発生すると予想されました。
#!/bin/bash
paste <(awk '{print $1,$2,$3,...$19,$20}' Precipitation.csv ) > aaaaa1
paste <(awk '{print $21,$22,$23,...$39,$40}' Precipitation.csv ) > aaaaa2
paste <(awk '{print $41,$42,$43,...$99,$100}' Precipitation.csv ) > aaaaa3
コードを修正するのに役立ちますか?
答え1
これはケースのようです。cut
以下より良いでしょうawk
:
cut -d , -f1-20 Precipitation.csv > aaa1
cut -d , -f21-40 Precipitation.csv > aaa2
cut -d , -f41-100 Precipitation.csv > aaa3
-d ,
区切り文字(カンマ、入力をCSVと呼びますが変更できます)を指定します。含めて、-f N-M
出力に表示するフィールドを選択します。フィールドにカンマが含まれていると破損する可能性があります。この場合、実際のCSVパーサーが必要になるかもしれませんが、実際に不可能な場合は何かを一緒に投げることができます。N
M
出力は入力と同じ区切り文字を使用します。 GNUのcut
サポート--output-delimiter=STRING
別の区切り文字を設定するオプションがありますが、他の人はそうしないようです。 FreeBSDにはcut
以下が含まれます-w
スペースで分割オプションがawk
デフォルト値に近い。これらの動作の1つを他の場所で実装するには、区切り文字の前/後を変換するのがおそらく最善の選択です。
答え2
フォローアップマイケル・ホーマーの答え:
ksh
zsh
プロセス置換(、、、)をサポートするシェルを使用してファイルを複数回読み取るのを防ぐには、次の手順を実行しますbash
。
tee < Precipitation.csv >(cut -d, -f1-20 > aaa1) >(cut -d, -f21-40 > aaa2) |
cut -d, -f41- > aaa3
答え3
そしてperl
:
perl -F',' -anle 'print join ",", @F[0..19]' Precipitation.csv > aaa1
perl -F',' -anle 'print join ",", @F[20..39]' Precipitation.csv > aaa2
perl -F',' -anle 'print join ",", @F[40..99]' Precipitation.csv > aaa3
答え4
入力ファイルを一度だけ読み取るので、より良いパフォーマンスが得られます。
awk '{out1=$1; for(i=2; i<=20; i++) {out1 = (out1 FS $i)}
out2=$21; for(i=22; i<=40; i++) {out2=(out2 FS $i)}
out3=$41; for(i=42; i<=100; i++) {out3=(out3 FS $i)}
print out1 > "aaaaa1"; print out2 > "aaaaa2"; print out3 > "aaaaa3"}' Precipitation.csv
または、次のコマンドですべてのフィールド番号を入力できます。 「...」をすべての必須フィールド番号に置き換えます。
awk '{print $1,$2,$3,...$19,$20 > "aaaaa1";
print $21,$22,$23,...$39,$40 > "aaaaa2";
print $41,$42,$43,...$99,$100 > "aaaaa3"}' Precipitation.csv