awk를 사용하여 새 줄 인쇄

awk를 사용하여 새 줄 인쇄

파일 수가 많고 특정 행을 가져온 다음 가져온 데이터를 스프레드시트에 넣어야 합니다. 내 파일에 표시된 내용은 다음과 같습니다.

Name: w

Age: x

Height: y

Weight: z

나이, 키, 몸무게만 원하므로 먼저 다음을 실행합니다.

grep -E 'Age|Height|Weight' [input file] > output.txt

파일 수가 많기 때문에 이제 출력은 다음과 같습니다.

Age 1
 
Height 1

Weight 1

Age 2

Height 2

Weight 2

etc...

지금 내가 원하는 것은 awk 스크립트를 실행하여 새 output.txt 파일을 통과하고 먼저 "Age"라는 단어가 포함된 각 줄을 찾아 인쇄하는 것입니다. 모든 "나이" 계산이 완료되면 키와 몸무게가 계산됩니다. 나는 스크립트를 실행했습니다 :

awk -F"\t" '/Age/ {print} /Height/ {print}' output.txt >output2.txt

하지만 원본 출력 파일처럼 인쇄하면 됩니다. 모든 연령을 완료한 후 키를 찾도록 어떻게 변경합니까?

편집하다:

내가 원하는 출력은 파일입니다

1세

2세

높이 1

높이 2

무게 1

무게 2

등..

명확히 하기 위해 age1은 "age" 등을 포함하는 file1의 행입니다.

답변1

awk는 기본적으로 파일을 한 번만 실행하고 모든 블록을 순서대로 실행하므로 출력이 제공됩니다. 다음을 사용하여 원하는 동작을 얻을 수 있습니다.정렬파일을 한 번만 처리하면서 언제든지 줄을 저장하세요.

BEGIN {
    AgeIndex = 1
    HeightIndex = 1
}
/Age/ {
    ages[AgeIndex] = $0
    AgeIndex+=1
}
/Height/ {
    heights[HeightIndex] = $0
    HeightIndex+=1
}
END {
    for (x = 1; x < AgeIndex; x++)
        print ages[x] "\n"
    for (x = 1; x < HeightIndex; x++)
        print heights[x] "\n"
}

저장한 filter.awk후 다음을 실행하세요.

awk -f filter.awk output.txt > output2.txt

원하는 출력을 얻으십시오.

$ awk -f filter.awk < data
Age 1

Age 2

Height 1

Height 2

우리가 하고 있는 일은 두 개의 배열을 만들고 ages일치 heights하는 각 행을 그 배열에 저장하는 것입니다. AgeIndex도달한 거리를 배열로 저장합니다. 마지막으로, 저장한 각 줄(원하는 추가 줄바꿈 포함)을 먼저 모든 연령, 그 다음에는 모든 높이로 인쇄합니다.

배열은 전체 파일을 메모리에 보관하게 되므로 파일이 특히 큰 경우 전체 파일을 여러 번 반복하는 데 걸리는 시간과 메모리 사용량을 절충해야 합니다. 이 시점에서는 본질적으로 다른 언어와 동일한 프로그램입니다. awk를 사용해야 할 특별한 이유가 없다면 다른 언어를 선호할 수도 있습니다. 솔직히 말해서, 나는 제안하고 싶습니다 - awk는 여기서 당신에게 별로 도움이 되지 않습니다.

답변2

그리고 gawk:

$ awk -F"\t" '
    { a[$1]++ }
    END {
        n = asorti(a,b);
        for (i = 1; i <= n; i++) {
            print b[i];
            if (i%2 == 0) {
                printf "\n";
            }
        }
    }
' output.txt
Age 1
Age 2

Height 1
Height 2

Weight 1
Weight 2

답변3

나는 빈 줄이 실제 파일의 일부라고 생각하지 않거나 적어도 신경 쓰지 않습니다. 그렇다면 필요한 것은 다음과 같습니다 sort.

$ cat output.txt
Age 1
Height 1
Weight 1
Age 2
Height 2
Weight 2

$ sort output.txt
Age 1
Age 2
Height 1
Height 2
Weight 1
Weight 2

그러나 파일이 너무 커서 메모리에 저장할 수 없는 경우가 아니면 전체 작업을 한 단계로 수행하는 것이 더 간단할 수 있습니다.

grep -whE 'Age|Height|Weight' *txt | sort > outfile

위 명령은 현재 디렉터리( )에서 Age이름이 또는로 끝나는 모든 파일을 검색합니다. "전체 단어만 일치"(즉, 일치하지 않음)를 의미합니다. 이것이 없으면 여러 입력 파일이 제공될 때 파일 이름이 일치하는 줄과 함께 인쇄되기 때문에 필요합니다. 확장된 정규 표현식을 사용하여 OR을 제공합니다.HeightWeighttxt*txt-wAgeAgeing-h-E|

노트: 어떤 이유로든 각 항목 사이에 빈 줄을 추가하고 싶은 경우(명령으로 생성되는 내용이 아님 grep) 다음을 사용하여 추가할 수 있습니다.

grep -whE 'Age|Height|Weight' *txt | sort | sed 's/$/\n/'

$ for i in {1..3}; do echo -e "Name $i\nAge $i\nHeight $i\nWeight $i" > $i.txt; done
$ for f in *txt; do echo " -- $f --"; cat $f; done
 -- 1.txt --
Name 1
Age 1
Height 1
Weight 1
 -- 2.txt --
Name 2
Age 2
Height 2
Weight 2
 -- 3.txt --
Name 3
Age 3
Height 3
Weight 3

$ grep -whE 'Age|Height|Weight' *txt | sort
Age 1
Age 2
Age 3
Height 1
Height 2
Height 3
Weight 1
Weight 2
Weight 3

어쨌든, sort그것이 당신에게 적합하지 않더라도 대신 Perl에서 다음과 같은 작업을 수행할 것입니다 awk(이것은 당신이 추가 빈 줄을 원한다고 가정하지만 아마도 당신은 그렇지 않을 것입니다):

$ perl -ane '$k{$F[0]}.=$_."\n" if /./; 
    END{print $k{$_},"\n" for sort keys (%k)}' output.txt 
Age 1

Age 2


Height 1

Height 2


Weight 1

Weight 2


 

필요하지 않은 경우 head -n -2마지막 두 개의 빈 줄을 제거하는 데 사용할 수 있습니다.

답변4

python이 문제에 대한 해결책:

from collections import defaultdict
f = open("output.txt", "r")
d = defaultdict(list)
for line in f:
   line = line.strip()
   if line != '':
     arr = line.split(" ")
     d[arr[0]].append(arr[1])
print d.items()

첫 번째 열을 사용하여 해시하고 목록에 넣었습니다.

관련 정보