인쇄할 열을 지정하는 문자열을 awk에 어떻게 전달합니까?

인쇄할 열을 지정하는 문자열을 awk에 어떻게 전달합니까?

공백으로 구분된 열이 많은 파일이 있습니다. 일부 수치 기준에 따라 특정 열을 동적으로 인쇄하고 싶습니다. 예를 들어:

]$ cols=$(for i in `seq 1 3`; do echo -n "\$$[$[i-1]*6+1],\$$[$[i-1]*6+2],\$$[$[i-1]*6+3],\$$[$[i-1]*6+4+66],\$$[$[i-1]*6+5+66],\$$[$[i-1]*6+6+66],"; done)

그러면 인쇄하려는 열이 제공됩니다.

]$ echo ${cols%?}
$1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84

awk에 문자열로 전달하면 원하는 것을 얻지 못합니다.

]$ awk -v cols=${cols%?} '{print cols}' file-testawk | head -2
$1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84
$1,$2,$3,$70,$71,$72,$7,$8,$9,$76,$77,$78,$13,$14,$15,$82,$83,$84 

awk는 이를 열 식별자가 아닌 문자열로 처리합니다.

올바르게 인식된 방식으로 인쇄하기 위해 awk에 열 목록을 어떻게 전달합니까? 나는 다음과 같이 간단하고 대략 한 줄의 솔루션을 찾고 있습니다.

cols=$(for i in `seq 1 3`; do echo -n "\$$[$[i-1]*6+1],\$$[$[i-1]*6+2],\$$[$[i-1]*6+3],\$$[$[i-1]*6+4+66],\$$[$[i-1]*6+5+66],\$$[$[i-1]*6+6+66],"; done); awk -v cols=${cols%?} '{print cols}' file-testawk > file.out

답변1

awk에는 평가와 유사한 기능이 없지만 awk -fbash 프로세스 교체와 결합된 기능(파일에서 스크립트 읽기)을 사용하여 트릭을 수행할 수 있습니다.

$ a="\$1,\$4"
$ echo "$a"
$1,$4
$ a="{print $a}"
$ echo "$a"
{print $1,$4}
$ awk -f <(echo "$a") <<<"one two three four five"
one four

답변2

용법: ./pass_numbers_to_awk.sh댓글에 설명이 있습니다.

#!/bin/bash

#generate random string of numbers - simulation column's numbers 
for i in {1..2}; do
    for j in {1..3}; do
        num=$(( (i-1) * 6 + j ))
        #numbers separated by vertical bar symbol 
        string_of_numbers+="${num}|"
    done
done

# pass to awk string like a "1|2|3|7|8|9|13|14|15|", 
# removing last vertical bar "|"
##
# use the awk split function - for information 
# look at the 'man mawk | grep -A 3 split\(s,A,r\)'
##      
# go through array and print specified columns.

awk -v string_from_bash="${string_of_numbers%?}" '
BEGIN {
    num_of_cols = split(string_from_bash, array_of_columns, "|");
}
{
    for (i = 1; i <= num_of_cols; i++) {

        # Prevent trailing spaces emergence
        OFS = (i > 1) ? " " : ""

        printf "%s%s", OFS, $array_of_columns[i];
    }
    printf "\n";
}' < input.txt

테스트용 input.txt 파일을 만듭니다. ./create_table.sh > input.txt

#!/bin/bash

for i in {A..O}; do
    for j in {1..10}; do
        echo -n "column_${j} "
    done
    echo
done

답변3

awk다음과 같은 지수 계산을 잘 수행하십시오.

awk -v N=3 '
   {
   for ( i=1; i<= N; ++i )
      print $((i-1)*6+1), $((i-1)*6+2), $((i-1)*6+3), $((i-1)*6+4+66), $((i-1)*6+5+66), $((i-1)*6+6+66)
   }
' data.file

기본 아이디어는 변수에 저장된 숫자를 awk에 제공하면 해당 숫자에 해당하는 필드를 얻을 수 있다는 것 i입니다 . 여기의 경우처럼 Now 도 표현식이 될 수 있습니다.awk$(i)i

관련 정보