텍스트 파일의 쉼표로 구분된 필드 수

텍스트 파일의 쉼표로 구분된 필드 수

이 파일을 읽기 위해 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은 입력 파일의 행이고 나머지는 사용자가 요청한 것입니다.

관련 정보