입력(탭으로 구분된 필드)

입력(탭으로 구분된 필드)

열의 숫자가 다른 파일을 하위 집합으로 만들고 출력에 여러 파일을 만들어야 합니다. 루프에서 이 작업을 수행하려고 하는데 반복자가 작동하지 않습니다.

입력(탭으로 구분된 필드)

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가 기본 공백 구분 기호를 제거하고 분할하도록 허용할 수 있습니다.

관련 정보