Bash의 awk 명령에서 bash 변수를 사용하는 방법

Bash의 awk 명령에서 bash 변수를 사용하는 방법

이전에 생성된 변수 세트를 사용하여 a.ped_snps.temp라는 파일의 열을 필터링하고 bash for 루프에서 awk를 사용하고 싶습니다.

이를 위해 bash 변수를 만들었습니다: var_i_1, var_i_2, ... var_i_n_blocks는 하한으로 var_f_1, var_f_2, ... var_f_n_blocks는 상한으로 사용됩니다.

앞에서 언급한 n_blocks는 var_i_1과 var_f_1 등으로 구분된 열을 사용하여 생성될 파일 수입니다. 다음 스크립트를 사용했습니다.

n_blocks=$(wc -l "a.temp" | awk '{print $1}') # number of blocks to be created, a.temp is the file with the number of blocks

for i in $(seq 1 1 $n_blocks)            # to iterate of first to n_blocks 
    do
    awk -v v_i="$var_i_$i" -v v_f="$var_f_$i" '{     # to declare variables of lower ($var_i_$i) and upper ($var_f_$i) bounds for each iteraction to awk command
    for (i=v_i;i<=v_f;i++) {printf (i==1?"":FS)$i}; print ""     # for statement to print all comlumns between specified in v_i and v_f variables in each iteraction
    }' <a.ped_snps.temp > block_$i.txt       # print one txt file with each block for each iteraction
done

이 코드는 실행되어 for 명령에 지정된 올바른 반복 횟수로 파일을 제공하지만 각 파일의 첫 번째 열만 출력에 인쇄됩니다.

awk(아래)와 var_i_1 및 var_f_1 bash 변수(이전에 각각 저장된 값 2 및 4 포함)만 사용하면 출력(block_1.txt)에는 필수 열 $2, $3 및 $4 등만 포함됩니다. 다른 블록.

awk -v v_i="$var_i_1" -v v_f="$var_f_1" '{     # declare variables of lower ($var_i_1) and upper ($var_f_1) bounds for first block (set of cloumns)
    for (i=v_i;i<=v_f;i++) {printf (i==1?"":FS)$i}; print ""     # for statement to print only comlumns between specified in v_i and v_f variables for first block
}' <a.ped_snps.temp > block_1.txt       # print one txt file only with a set of columns specified in v_i and v_f variables

그렇다면 이 코드를 bash에서 구현하는 데 도움을 줄 수 있는 사람이 있나요? 어쨌든, 이전에 bash의 awk 명령에서 생성한 bash 변수를 사용하고 싶습니다.

내 설명이 명확하기를 바랍니다.

미리 감사드립니다.

답변1

$var_i_$i값 등으로 확장 $var_i_1할 것으로 예상하는 것처럼 보이지만 $var_i_2불행히도 그렇지 않습니다. 이를 설명하기 위해 다음과 같이 설정한다고 가정합니다.

$ var_i_1=23; var_i_2=45; var_i_3=67

그 다음에

$ for i in $(seq 1 3); do awk -v v_i="$var_i_$i" 'BEGIN{print v_i}'; done
1
2
3

여기서 일어나는 일은 쉘이 $var_i_$i다음과 같이 해결된다는 것입니다.$var_i_ 연관된 $i. $var_i_설정되지 않거나 null일 수 v_i있고 v_f단순히 루프 인덱스 값을 상속받을 수 있기 때문입니다 i.

원하는 것을 간접적으로 달성하는 몇 가지 추악한 방법이 있습니다.

$ for i in $(seq 1 3); do awk -v v_i="$(eval echo \${var_i_$i})" 'BEGIN{print v_i}'; done
23
45
67

그러나 bash는 배열을 지원하므로 더 깔끔한 해결책은 배열을 var_i합계 var_f값으로 사용하는 것입니다.

$ var_i=(23 45 67)

그런 다음 (배열은 0 인덱스라는 것을 기억하십시오)

$ for i in $(seq 0 2); do awk -v v_i="${var_i[i]}" 'BEGIN{print v_i}'; done
23
45
67

관련 정보