내가 있는 디렉터리에는 수천 개의 파일이 있지만 필터링하려는 파일에는 모두 다음 구문이 있습니다.*.imputed.*_info
awk를 사용하여 데이터의 다섯 번째 열 값이 0.50보다 큰 각 파일의 레코드를 필터링하고 싶습니다. 다음 방법을 사용하면 됩니다 awk '{if($5 >= .5) {print}}' filename
.
그것도 작동합니다. 그런 다음 500개 정도의 파일 전체를 반복하면서 이 기준을 충족하는 각 파일의 레코드를 연결해 보았습니다.
다음을 시도했지만 구문이 올바르지 않습니다.
touch snplist.txt
for name in *.imputed.*_info; do
snps="awk '{if($5 >= .5) {print}}' $name"
cat snplist.txt "$snps" > snplist.txt
done
답변1
코드는 반복할 때마다 출력 파일을 덮어씁니다. 당신도 실제로 전화를 걸지 않았습니다 awk
.
당신이하고 싶은 일은 다음과 같습니다
awk '$5 >= 0.5' ./*.imputed.*_info >snplist.txt
그러면 awk
모든 파일이 한 번에 호출되고 쉘의 확장된 와일드카드 패턴 순서에 따라 하나씩 반복됩니다. 파일에 있는 줄의 5번째 열이 0.5보다 크거나 같으면 해당 줄이 출력됩니다( snplist.txt
). 이는 조건과 연결된 작업(블록)이 없는 경우 {...}
기본 작업이 현재 행을 출력하는 것이기 때문에 작동합니다.
당신이 가지고 있다면큰파일 수(천 개)로 인해 "매개변수 목록이 너무 김" 오류가 발생할 수 있습니다. 이 경우 다음을 반복해야 할 수도 있습니다.
for filename in ./*.imputed.*_info; do
awk '$5 >= 0.5' "$filename"
done >snplist.txt
결과는 awk
변수에 저장될 필요가 없습니다. 여기서는 출력됩니다.주기(따라서 루프 내의 모든 명령)은 로 리디렉션됩니다 snplist.txt
.
수천 개의 파일의 경우 awk
각 파일을 개별적으로 호출해야 하므로 속도가 매우 느립니다.
작업 속도를 높이려면 단일 호출에 파일이 너무 많으면 다음과 같은 방법을 awk
사용하는 것이 좋습니다 .xargs
printf '%s\0' ./*.imputed.*_info | xargs -0 awk '$5 >= 0.5' >snplist.txt
그러면 파일 이름 목록이 생성되어 printf
null로 끝나는 목록으로 전달됩니다. xargs
유틸리티 xargs
는 이를 받아 awk
시작합니다 .가능한 한 많이한 번, 일괄적으로. 전체 파이프라인의 출력은 로 리디렉션됩니다 snplist.txt
.
이 대안은 사용자 가 Null로 끝나는 입력을 읽기 위한 비표준 옵션을 구현하는 명령이 xargs
있는 Linux와 같은 Unix를 사용한다고 가정합니다 . 또한 쉘을 사용하고 있다고 가정합니다 .xargs
-0
bash
내장 printf
유틸리티( ksh
OpenBSD의 기본 셸은 내장 유틸리티가 없으므로 여기서는 작동하지 않습니다).
zsh
쉘 의 경우 (즉, 아님 bash
):
autoload -U zargs
zargs -- ./*.imputed.*_info -- awk '$5 >= 0.5' >snplist.txt
이는 기본적으로 로드 가능한 쉘 함수 zargs
를 다시 구현한 것 입니다. 자세한 내용은 (함수 로딩 후) 및 설명서를 참조하세요.xargs
zsh
zargs --help
zshcontrib(1)
답변2
이렇게 하세요:
awk '$5 >= .5' *.imputed.*_info > snplist.txt
답변3
find
나는 이런 종류의 물건을 사용하는 습관이 있습니다.
find . -type f -name "*.imputed.*_info" -exec awk '$5 >= 0.5' {} \; > ./snplist.txt