큰 데이터 파일이 있고 이를 열 1의 값을 기준으로 더 작은 파일로 분할하고 싶습니다. 예를 들어 열 1에는 100개의 행을 만들기 위해 1에서 10까지의 숫자가 10번 있고 숫자가 '1' 또는 '2인 모든 줄을 원합니다. ' 또는 '3' 등을 자체 파일에 포함합니다(정렬하지 않는 것이 좋음). 또한 명령을 10번 실행하고 싶지 않으므로 루프에 포함되기를 원합니다.
내 파일은 다음과 같습니다.
내가 시도한 명령은 다음과 같습니다.
cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done
요약하자면 ID.txt 파일(예: '1')에서 값을 읽은 다음 첫 번째 줄에 '1'이 있는 모든 행을 추출하여 1.txt라는 파일에 넣은 다음 2로 반복합니다. 3, 4 등.
그런데 왠지 '$1 == ${line}' 부분이 작동하지 않는 것 같아요
답변1
-v
당신은 다음과 같은 옵션을 찾고 있습니다 awk
:
-v var=val
--assign var=val
Assign the value val to the variable var, before execution of
the program begins. Such variable values are available to the
BEGIN rule of an AWK program.
이 같은:
cat ID.txt |
while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done
다음과 같이 표현하는 것이 더 좋습니다(cat을 쓸데없이 사용하지 않음).
while read line; do
awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt
그러나 이는 매우 느리고 비효율적입니다. 의 각 줄 awk
전체에 대해 명령을 실행하고 있습니다 . 그냥 그 자체 를 읽고 일치하는 줄을 인쇄하면 어떨까요 ?test.txt
ID.txt
ID.txt
awk
awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt
ID.txt
위의 내용은 배열의 첫 번째 필드를 저장합니다 a
. "입력 스트림의 현재 줄"과 "현재 파일의 현재 줄"을 의미하는 특수 변수입니다 NR
. 두 파일은 첫 번째 파일을 읽을 때만 서로 동일합니다. 따라서 첫 번째 파일의 줄에서만 실행됩니다. 두 번째 부분 은 다음 줄로 건너뛰도록 지시 하므로 실행되지 않습니다 .FNR
awk
NR==FNR{a[$1]++; next}
next
awk
두 번째 부분에서는 현재 줄의 첫 번째 필드(두 번째 파일에서만 실행된다는 점을 기억하세요)가 배열에 있는지 확인하고 a
(즉, 에 있음을 의미함 ID.txt
), 그렇다면 해당 줄을 "field1.0"이라는 파일에 인쇄합니다. txt"