이전에 생성된 변수 세트를 사용하여 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