次のファイルがあります。
id name age
1 ed 50
2 joe 70
id
私は印刷と列だけが欲しいですage
。今、私は次を使いますawk
。
cat file.tsv | awk '{ print $1, $3 }'
ただし、これには列番号を知る必要があります。列番号の代わりに列名(最初の行に指定)を使用する方法はありますか?
答え1
たぶん、次のようなものがあります。
$ cat t.awk
NR==1 {
for (i=1; i<=NF; i++) {
ix[$i] = i
}
}
NR>1 {
print $ix[c1], $ix[c2]
}
$ awk -f t.awk c1=id c2=name input
1 ed
2 joe
$ awk -f t.awk c1=age c2=name input
50 ed
70 joe
コマンドラインに印刷する列を指定するには、次のようにします。
$ cat t.awk
BEGIN {
split(cols,out,",")
}
NR==1 {
for (i=1; i<=NF; i++)
ix[$i] = i
}
NR>1 {
for(i=1; i <= length(out); i++)
printf "%s%s", $ix[out[i]], OFS
print ""
}
$ awk -f t.awk -v cols=name,age,id,name,id input
ed 1 ed 50 1
joe 2 joe 70 2
(-v
ブロックで定義された変数を取得するためのスイッチに注意してくださいBEGIN
。)
答え2
csvkit
入力データをcsv形式に変換し、csvツールを使用します。csvcut
からcsvkit
:
$ cat test-cols.dat
id name age
1 ed 50
2 joe 70
csvkitをインストールします。
$ pip install csvkit
tr
squeezeオプションと一緒に使用して、-s
有効なcsvファイルに変換して適用しますcsvcut
。
$ cat test-cols.dat | tr -s ' ' ',' | csvcut -c id,age
id,age
1,50
2,70
古いデータ型に戻すには、次のものを使用できます。tr ',' ' ' | column -t
$ cat test-cols.dat | tr -s ' ' ',' | csvcut -c id,age | tr ',' ' ' | column -t
id age
1 50
2 70
ノート
csvkitはさまざまな区切り記号(共有オプション
-d
または--delimiter
)、しかしcsvファイルを返します。ファイルが列を区切るために空白のみを使用する場合(タブがまったくありません)、次のことが機能します。
$ csvcut -d ' ' -S -c 'id,age' test-cols.dat id,age 1,50 2,70
ファイルがタブ区切りの列を使用している場合は、
csvformat
TSVファイルを再インポートするために使用できます。$ csvcut -t -c 'id,age' test-cols.dat | csvformat -T id age 1 50 2 70
私が確認した結果タブは1つだけ許可されます。
csvlook
テーブルはMarkdownテーブル形式でフォーマットできます。$ csvcut -t -c "id,age" test-cols.dat | csvlook | id | age | | -- | --- | | 1 | 50 | | 2 | 70 |
UUOC(役に立たない猫):私はこのようにコマンドを整理するのが好きです。
答え3
ただPerlソリューションを山の上に投げてください:
#!/usr/bin/perl -wnla
BEGIN {
@f = ('id', 'age'); # field names to print
print "@f"; # print field names
}
if ($. == 1) { # if line number 1
@n = @F; # get all field names
} else { # or else
@v{@n} = @F; # map field names to values
print "@v{@f}"; # print values based on names
}
答え4
価格と比較して良い値。選択した出力順序に関係なく、ソースの列数と印刷する列数を処理できます。
例えば。呼ぶ:script-name id age
outseq=($@)
colnum=($(
for ((i; i<${#outseq[@]}; i++)) ;do
head -n 1 file |
sed -r 's/ +/\n/g' |
sed -nr "/^${outseq[$i]}$/="
done ))
tr ' ' '\t' <<<"${outseq[@]}"
sed -nr '1!{s/ +/\t/gp}' file |
cut -f $(tr ' ' ','<<<"${colnum[@]}")
出力
id age
1 50
2 70