awk 독립 3열

awk 독립 3열

다음과 같은 파일이 있습니다(열은 탭으로 구분되어 있으며 공백이 포함될 수 있음).

    0637    apple    8528    1392    orange    1390    8528    unknown fruit    7537    1039    banana    1892    0989    pineapple    7537    8528    melon    7537    8528    grape    7537    8528    (null)    (null)

결과를 얻으려면 이를 3개 열마다 분할한 다음 grep해야 합니다 ( 대용량 파일에서는 grep보다 훨씬 빠르기 때문에 [0-9]$이것을 사용합니다 ).awk

0637    apple    8528
1392    orange    1390
8528    unknown fruit    7537
1039    banana    1892
0989    pineapple    7537
8528    melon    7537
8528    grape    7537

이제 나에겐 이것이 있다아름다운이를 수행하는 명령:

awk -F\\t '{print $2 "\t" $3 "\t" $4 "\n" $5 "\t" $6 "\t" $7 "\n" $8 "\t" $9 "\t" $10 "\n" $11 "\t" $12 "\t" $13 "\n" $14 "\t" $15 "\t" $16 "\n" $17 "\t" $18 "\t" $19 "\n" $20 "\t" $21 "\t" $22 "\n" $23 "\t" $24 "\t" $25}' filename | awk '/[0-9]$/'

cut또한 동일한 작업을 수행하는 추악한 명령이 있습니다 . 나는 아직 awk를 배우는 중이므로 이 작업을 수행하는 더 합리적인 방법이 있다고 확신합니다. 또한, 나는 어쩌면초과하면 문제가 발생합니다$25. 도와주세요?

답변1

이것은 작동합니다:

$ cat splitnum.awk
#!/bin/awk -f
BEGIN {
    FS = OFS = "\t"
}
{
    for ( i = 1; i < NF; i = i + 3) {
        if ( $(i+2) ~ /[0-9]+/ ) {
            print $i, $(i+1), $(i+2)
        }
    }
}
$ awk -f splitnum.awk filename

아니면 한 줄에 모두 작성하세요:

awk 'BEGIN{FS=OFS="\t"}{for (i=1;i<NF;i=i+3){if ($(i+2) ~ /[0-9]+/) {print $i, $(i+1), $(i+2)}}}' filename

기본적으로 데이터 필드를 한 번에 3개씩 반복하면서 세 번째 필드가 숫자로 구성되어 있는지 확인합니다.

답변2

필드가 하나 이상의 탭으로 구분되어 있고 각 필드에 탭이 아닌 공백이 포함될 수 있다고 가정하면 다음이 작동합니다.

( IFS=$'\t'; printf '%s %s %s\n' $(<input_file) )

(하위 쉘은 편리하며 IFS호출 쉘을 변경할 필요가 없습니다.)

또는 필드가 하나 이상의 공백과 탭으로 구분되어 있고 각 필드에 공백이나 탭이 없으면 다음이 작동합니다.

printf '%s %s %s\n' $(<input_file)

답변3

awk -F'\t' '{for(i=1;i<=NF;i++)if(!(i%3))$i=$i "\n"}1' file

답변4

이상한 싫어하는 사람들을 위해 :

perl -pe 's/(\d+)\s+(\d+)/$1\n$2/g' | 
perl -lnpe 's/^\s*(\d+)\s+([^\d]+?)\s+(\d+).*/$1\t$2\t$3/' |
egrep '[0-9]$'

관련 정보