쉼표로 구분된 텍스트에서 열 추출

쉼표로 구분된 텍스트에서 열 추출

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

-F,분할할 모드를 지정합니다. -F암시적 설정-a

-a와 함께 사용하면 자동 분할 모드가 켜집니다 -n. 배열에 대한 암시적 분할 명령은 @F생성된 암시적 while 루프 내에서 가장 먼저 수행됩니다 -n. -a암시적 설정-n

-nPerl은 프로그램 주위에 루프가 있다고 가정하여 파일 이름 인수를 반복하게 합니다 sed -n.awk

-l자동 줄 바꿈 처리를 활성화합니다. 두 가지 다른 효과가 있습니다. 먼저, 입력 레코드 구분 기호( )를 자동으로 자릅니다 \n. 둘째, 출력 레코드 구분 기호를 에 할당합니다 \n.

-e한 줄 프로그램을 입력하는 데 사용됩니다.

따라서 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;
}

관련 정보