カンマ区切りのテキストから列を抽出する

カンマ区切りのテキストから列を抽出する

20K行を含む長いカンマ区切りファイルがあります。例は次のとおりです。

"","id","number1","number2","number3","number4","number5","number6","number7"
"1","MRTAT_1of3.RTS",17.1464602742708,17.1796255746079,17.1132949739337,0.996138996138996,-0.0055810322632996,1,1
"2","MRTAT_2of3.RTS",3.88270908946253,6.13558056235995,1.62983761656512,0.265637065637066,-1.91247162787182,0.718084341158075,1
"3","MRTAT_3of3.RTS",3.87323328936623,1.22711611247199,6.51935046626046,5.31274131274131,2.40945646701554,0.676814519398334,1

id、number4、number5、number 6を含む列を印刷し、タブ区切りを使用してnumber4条件が4.0より大きいと設定したいと思います。以下はいくつかのサンプル出力です。

id         number4           number5           number6
MRTAT_3of3.RTS 5.31274131274131  2.40945646701554  0.676814519398334

答え1

awk -F , -v OFS='\t' 'NR == 1 || $6 > 4 {print $1, $6, $7, $8}' input.txt

答え2

私はawkが最善の解決策であることに同意します。あなたできるこれはbashの他のいくつかのツールを使って行うことができます:

cut -d , -f 2,6,7,8 filename | {
    read header
    tr , $'\t' <<< "$header"
    while IFS=, read -r id num4 num5 num6; do
        # bash can only do integer arithmetic
        if [[ $(bc <<< "$num4 >= 4.0") = 1 ]]; then
           printf "%s\t%s\t%s\t%s\n" "$id" "$num4" "$num5" "$num6"
        fi
    done
}

答え3

上記のawkスクリプトに勝つ方法は実際にはありませんが、ここにRubyソリューションがあります。

#!/usr/bin/ruby1.9.1

puts "id\tnumber4\tnumber5\tnumber6"

ARGF.each_line do |line|
  arr = line.split(',')
  puts "#{arr[1]}\t#{arr[5]}\t#{arr[6]}\t#{arr[7]}" if arr[5].to_f > 4.0
end

スクリプトを使用するには、ファイル名で呼び出すか、ファイルをパイプでリンクします。

答え4

Perlソリューション:

perl -F, -le '$, = "\t"; print @F[1,5,6,7] if $F[5] > 4 || $. == 1' file

-F,分割するモードを指定します。-F暗黙の設定-a

-aと一緒に使用すると、自動分割モードがオンになります-n。配列に対する暗黙の分割コマンドは、生成された暗黙の@Fwhileループ内で最初に実行されます-n-a暗黙の設定-n

-nPerlは、プログラムの周りにループがあると仮定してファイル名引数を繰り返すようにしますsed -nawk

-l自動改行処理を有効にします。 2つの異なる効果があります。まず、入力レコード区切り記号()を自動的に切り捨てます\n。次に、出力レコード区切り文字をに割り当てます\n

-e1行プログラムを入力するために使用されます。

したがって、perl -F, -le '$, = "\t"; print @F[1,5,6,7] if $F[5] > 4 || $. == 1'次のようにします。

use English;

$OUTPUT_RECORD_SEPARATOR = $INPUT_RECORD_SEPARATOR;

while (<>) { # iterate over each line of the each file
    chomp;
    @F = split(',');
    $OUTPUT_FIELD_SEPARATOR = "\t";
    print @F[1,5,6,7] if $F[5] > 4 || $INPUT_LINE_NUMBER == 1;
}

関連情報