이 파일을 읽기 위해 awk 문을 작성하려고 합니다.
A 1,2,3 *
A 4,5,6 **
B 1
B 4,5 *
다음과 같은 파일을 빌드합니다.
A 1,2,3 * 3 1 0.333
A 4,5,6 ** 3 2 0.666
B 1 1 0 0
B 4,5 * 2 1 0.5
이 새 파일에서 처음 세 개의 열은 원본 파일과 동일합니다. 네 번째 열에는 열 2의 쉼표로 구분된 요소 수가 포함되어야 합니다. 다섯 번째 열에는 열 3의 문자 수가 포함되어야 합니다. 마지막 열에는 열 4에서 열 5의 비율이 포함됩니다(즉, 열 5를 열 4로 나눈 값).
다음 코드를 시도하고 있습니다.
awk '{print $1"\t"$2"\t"$3"\t"(NF","$2 -1)"\t"length($3)"\t"(length($3)/(NF","$2-1))}' file1 > file2
그러나 나는 다음과 같은 결과를 얻습니다.
A 1,2,3 * 3,0 1 0.333333
A 4,5,6 ** 3,3 2 0.666667
B 1 2,0 0 0
B 4,5 * 3,3 1 0.333333
4열에서 제가 뭘 잘못하고 있는지 이해가 안 돼요.
답변1
(NF","$2 -1)
이것을 필드에서 쉼표로 구분된 요소의 수를 반환하는 함수로 생각하고 싶은 것 같지만 $2
그렇지 않습니다. NF
항상 필드 수입니다.기록.
대신 awk의 split
함수를 사용하여 split($2,a,",")
필드를 $2
배열로 분할 a
하고 요소 수를 반환할 수 있습니다.print 문에서 명시적인 "\t"를 사용하는 대신 출력 필드 구분 기호를 탭으로 설정하여 코드를 정리할 수도 있습니다.
awk '{l2=split($2,a,","); OFS="\t"; print $1, $2, $3, l2, length($3), length($3)/l2}' file1
답변2
Perl 접근 방식은 다음과 같습니다.
$ perl -lane '@k=($F[1]=~/,/g); $i=$#k+2; $l=length($F[2]);
print "@F $i $l ", $l/$i' file
A 1,2,3 * 3 1 0.333333333333333
A 4,5,6 ** 3 2 0.666666666666667
B 1 1 0
B 4,5 * 2 1 0.5
또는 printf
예쁜 형식을 사용하세요.
$ perl -lane '@k=($F[1]=~/,/g); $i=$#k+2; $l=length($F[2]);
printf "%s %-5s %-3s %s %3s %10f\n",@F,$i,$l,$l/$i' file
A 1,2,3 * 3 1 0.333333
A 4,5,6 ** 3 2 0.666667
B 1 1 0 0.000000
B 4,5 * 2 1 0.500000
설명하다
-lane
:-l
각 입력 줄에서 후행 줄 바꿈을 제거합니다.-a
각 입력 줄을 공백의 배열로 자동으로 분할합니다@F
. 이는-n
"입력 파일을 한 줄씩 읽음"을 의미하며-e
스크립트를 명령줄 인수로 전달할 수 있습니다.@k=($F[1]=~/,/g); $i=$#k+2;
: 배열에는@k
두 번째 필드에 있는 모든 쉼표가 포함됩니다. 그런 다음$i
최대 인덱스를@F
($#F
) 더하기 2로 설정합니다. i) 배열은 0부터 계산되기 때문에 2를 추가해야 합니다. 따라서 단일 요소 배열의 최대 인덱스는 0이 됩니다. 값이 아닌 쉼표를 계산하므로1,2
값은 두 개이지만 값 쉼표는 하나뿐이므로 1을 더해야 합니다 .$l=length($F[2]);
:$l
이제 3D 필드의 문자 수입니다.print "@F $i $l ", $l/$i
:요청된 정보를 인쇄합니다.@F
은 입력 파일의 행이고 나머지는 사용자가 요청한 것입니다.