これが基本的すぎる場合は申し訳ありません。列にヘッダー行(v1、v2など)があるcsvファイルがあります。 1列目と2列目を抽出するには、awk -F "," '{print $1 "," $2}' infile.csv > outfile.csv
。しかし、たとえば列1から10、20から25、および30から33を抽出する必要がある場合はどうでしょうか。補遺として、列番号ではなくヘッダー名で直接抽出する方法はありますか?
Awkで範囲を実行できるかどうかはわかりません。 forループを実行できますが、不要な列を除外するための処理を追加する必要があります。これを行う方が簡単でしょう。
awk -F, '{OFS=",";print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$20,$21,$22,$23,$24,$25,$30,$33}' infile.csv > outfile.csv
考慮すべき他の何か-これはより速く、より簡潔です:
cut -d "," -f1-10,20-25,30-33 infile.csv > outfile.csv
質問の2番目の部分については、ヘッダー行の処理方法を知っているPerlでスクリプトを記述し、stdinまたはファイルから列名を解析してからフィルター処理を行うと思います。それはおそらく、私が他のもののために持ちたいツールです。私はそれができると確信していますが、私は1つのライナーで行うことについて確信がありません。
@Tomで述べたように、cutとawkのアプローチは、引用符付きの文字列を含むCSVでは実際には機能しません。別の方法はpythonのモジュールです。これはコマンドラインツールcsvfilterを提供します。カットのように機能しますが、CSV列の引用を適切に処理します。
csvfilter -f 1,3,5 in.csv > out.csv
python(そしてそうする必要がある))がある場合は、次のように簡単にインストールできます。
pip install csvfilter
Csvfilterの列インデックスは0から始まることに注意してください(awkは$ 1から始まります)。詳細は https://github.com/codeinthehole/csvfilter/
他の人があなたの以前の質問に答えました。このため:
補遺として、列番号ではなくヘッダー名で直接抽出する方法はありますか?
試したことはありませんが、各ヘッダーのインデックスをハッシュに保存し、後でそのハッシュを使用してインデックスを取得できます。
for(i=0;i<$NF;i++){
hash[$i] = i;
}
その後、それを使用します:
j = hash["header1"];
print $j;
他の言語には、フィールド番号の範囲のショートカットがありますが、awkではありません。あなたの恐怖としてコードを書く必要があります;-)
awk -F, 'BEGIN {OFS=","} { print $1, $2, $3, $4 ..... $30, $33}' infile.csv > outfile.csv
Awkには、列指定子としてフィールド名を使用する直接関数はありません。
これがお役に立てば幸いです。
Forループを使用して、$ iでフィールドをアドレス指定できます。
ls -l | awk '{for(i=3 ; i<8 ; i++) {printf("%s\t", $i)} print ""}'
Tabulator は、ヘッダー行を持つcsvファイルを操作するためのUNIXコマンドラインツールのセットです。ファイルtest.csv:
から名前で列を抽出する例を次に示します
name,sex,house_nr,height,shoe_size
arthur,m,42,181,11.5
berta,f,101,163,8.5
chris,m,1333,175,10
don,m,77,185,12.5
elisa,f,204,166,7
次にtblmap -k name,height test.csv
が生成します
name,height
arthur,181
berta,163
chris,175
don,185
elisa,166
Perlがオプションの場合:
_Perl -F, -lane 'print join ",",@F[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32]'
_
_-a
_は、行を_@F
_フィールド配列に自動分割します。インデックスは0から始まります(awkのように1ではありません)
_-F,
_フィールド区切り文字は、
CSVファイルに引用符で囲まれたコンマが含まれている場合、Perlの_Text::CSV_XS
_などの本格的なCSVパーサーは、そのような奇妙さを処理するために特別に構築されています。
Perl -MText::CSV_XS -lne 'BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){@f=$csv->fields();print (join ",",@f[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32])}'
私はここで私の答えの中でより多くの説明を提供しました: gawkを使用してcsvファイルを解析
Awkを使用していませんが、これを実現する最も簡単な方法は、単に csvtool を使用することでした。 csvtoolを使用する他のユースケースもあり、列データ自体に引用符または区切り文字が含まれている場合、それらを適切に処理できます。
csvtool format '%(2)\n' input.csv
csvtool format '%(2),%(3),%(4)\n' input.csv
2を列番号に置き換えると、探している列データが効果的に抽出されます。