열의 숫자가 다른 파일을 하위 집합으로 만들고 출력에 여러 파일을 만들어야 합니다. 루프에서 이 작업을 수행하려고 하는데 반복자가 작동하지 않습니다.
입력(탭으로 구분된 필드)
abc 1
aaa 1
ccc 1
asd 2
sad 2
aaf 3
산출
파일 1:
abc 1
aaa 1
ccc 1
파일 2:
asd 2
sad 2
파일 3:
aaf 3
내 테스트는 이것이지만 빈 파일만 출력합니다.
for i in $(seq 1 3); do awk -F "\t" '{$2 == $i}' input > cluster.$i.txt; done
답변1
코드가 실패하는 이유는 스크립트 $i
내에서 쉘 변수를 사용 하려고 시도했지만 awk
잘못 수행했기 때문입니다. 작은따옴표 안의 텍스트는 '...'
쉘에서 문자 그대로 처리되므로 $i
쉘 변수의 값이 아닌 두 문자로 처리됩니다 $i
. 또한 비교를 작업으로 수행하려고 합니다(즉, 줄을 인쇄하는 암시적 작업이 없음을 의미).
값을 전달할 수 있습니다.awk
awk -F $'\t' -v i="$i" '$2 == i' input > "cluster.$i.txt"
또는 각 줄을 그 자체의 장점에 따라 처리하고 awk
완전히 피할 수도 있습니다.
while read field index
do
printf "%s\t%s\n" "$field" "$index" >> "cluster.$index.txt"
done < input
또는 다음을 awk
사용하여 동일한 작업을 수행할 수 있습니다.
awk '{ fname = "cluster." $2 ".txt"; print > fname }' input
답변2
$i
쉘 변수는 awk 표현식에서 내부적으로 참조되지 않습니다 i
. 명령줄을 사용하여 변수를 전달 -v i="$i"
하고 이를 plain 으로 인용할 수 있습니다 i
.
또한{....}
행동하나도 아니야무늬; mode가 true일 print
때 기본 동작( )을 수행하려는 것 같습니다. $2 == i
그래서
for i in $(seq 1 3); do
awk -F "\t" -v i="$i" '$2 == i'
input > cluster.$i.txt; done
그러나 각 인덱스에 대해 awk를 한 번 호출하는 대신 다음을 수행하는 것을 고려할 수 있습니다.
awk -F "\t" '{print > "cluster" $2 ".txt"}' input
입력을 직접 사용하여 $2
출력 파일 이름을 구성합니다.
공백 문자에 대한 필드 분할을 특별히 방지하려는 것이 아니라면 -F "\t"
awk가 기본 공백 구분 기호를 제거하고 분할하도록 허용할 수 있습니다.