나는 filter1.sh에 awk 명령이 포함되어 있다는 스크립트를 사용합니다.
bzip2 -dc File_1.tsv.bz2 | awk -F '\t' 'BEGIN {OFS=FS} { if (($7) > 50) print $0 }' > File_1.tsv
bzip2 -dc File_2.tsv.bz2 | awk -F '\t' 'BEGIN {OFS=FS} { if (($7) > 50) print $0 }' > File_2.tsv
bz2 파일을 열고 7열에서 50보다 큰 값을 필터링하고 출력을 새 tsv 파일에 씁니다.
이 필터링 단계를 수행해야 하는 여러 파일(약 200개, 서로 다른 디렉터리에 있음)이 있습니다(정확히 동일하지만 유사함).
내 질문은 이 목적을 위해 여러 파일을 전달하는 방법입니다. 별도의 INFILE(예: Python)을 통해 파일을 전달할 수 있습니까?
그것은 마치;
./filter1.sh pathtofiles.in
명령줄에서. 여기서 pathtofiles.in에는 파일 위치가 포함됩니다.
/home/users/gray_wolf/unix/File_1.tsv.bz2
/home/users/gray_wolf/unix/File_2.tsv.bz2
.
.
.
.
.
등.
미리 감사드립니다. ~엠
답변1
다음과 같이 하나의 출력 스트림에 모두 넣을 수 있습니다.
bzip2 -dc ./File_*.bz2 | filter
출력에서 별도의 파일에 쓰려면 어떻게든 스트림을 분리해야 합니다. 준비할 수 있다면 이는 이상적인 솔루션이 될 것입니다. 더 많은 정보를 통해 이 작업을 수행하는 데 도움을 받을 수 있습니다.
그렇지 않으면 각 입력 파일에 대해 필터를 한 번씩 호출할 수 있습니다.
for j in ./File_*.bz2
do [ -f "$j" ] &&
bzip2 -dc "$j" |
awk ... >"${j%.*}"
done
각 파일에 대해 파이프의 새 인스턴스를 호출해야 하기 때문에 이는 이상적이지는 않지만 실용적인 솔루션일 수 있습니다.
다른 스크립트 파일에서 이와 같은 루프를 가져온 for
다음 사용하려는 매개변수를 전달하려면 다음을 수행할 수 있습니다.
#!/bin/sh
for j do
case $j in
(*.bz2) [ -f "$j" ] &&
bzip2 -dc -- "$j" |
awk ... >"${j.*}"
esac
done
*.bz2
...이는 확장 없이 매개 변수가 전달될 수 있는 불쾌한 작업을 피하기 위해 모든 매개 변수의 이름이 확장으로 명시적으로 지정되도록 하기 위해 약간 더 복잡합니다 . , 다음과 같은 실행 파일을 작성하는 경우./script
POSIX를 사용하는 시스템에서는 다음과 /bin/sh
같이 호출할 수 있습니다.
./script ./File_*.bz2
답변2
노력하다
while read f
do
bzip2 -dc "$f" |
awk -F '\t' 'BEGIN{OFS=FS} $7 > 50' > "$(basename "$f" .bz2)"
done < list-of-file.txt
- awk는 File_1.tsv.bz2의 결과를 File_1.tsv에 기록하고 File_2, ... File_960에 기록합니다.
- 당신이 준 파일 목록
list-of-file.txt
> $(basename $f .bz2)
결과는 로컬 디렉터리에 생성됩니다.
답변3
Bash에서는 다음을 시도해 볼 수 있습니다:
for f in `cat $1`
do
bzip ...
done
이것은 모든 쉘에서 작동하지 않을 수 있으며, 이를 달성하는 다른 방법이 있다는 것은 의심할 여지가 없습니다. $1
"스크립트에 전달된 첫 번째 인수"를 의미합니다.
답변4
#!/bin/bash
while read -r j
do
[ -f "$j" ] &&
bzip2 -dc "$j" |
sed -r '/^([^\t]+\t){6}0*([1-9][0-9]{2,}|[6-9][0-9]|5[1-9])/! d' > "${j%.*}"
done <"$1"