특정 폴더에 많은 수의 파일이 있습니다. 열 4의 행에 0.5보다 큰 값이 하나 이상 있는 경우에만 이 파일을 하위 폴더로 이동하고 싶습니다. 별도의 명령에서 동일한 작업을 수행하고 싶지만 파일에 위의 값이 있는 행이 2개 이상 있습니다. 4열에서는 0.5입니다.
다음은 파일의 일반적인 형식입니다(헤더 포함).
col1 col2 col3 col4 col5 col6
ABC DEF 5.10 0.94 GHI JKL
MNO PQR 8.31 0.37 STU VWX
ABC DEF 6.49 0.84 GHI JKL
MNO PQR 3.32 0.21 STU VWX
4열의 숫자 중 일부는 과학적 표기법을 사용합니다: 8.934553871039306e-05
아래 코드는 열 4에서 0.5보다 큰 값이 하나 이상 있는 파일을 이동하기 위해 지금까지 시도한 것입니다. 결과적으로 조건과 일치하지 않는 파일이라도 모든 파일을 하위 폴더로 이동하게 됩니다.
#!/bin/bash
find . -type f -exec awk '$4 >= 0.5' {} \; -exec mv -n {} ./NewFolder/ \;
답변1
명령이 작동하도록 하려면 awk
일치하는 항목이 있으면 코드 0으로 종료해야 하고, 일치하는 항목이 없으면 0이 아닌 종료 코드로 종료해야 합니다.
또한 숫자가 아닌 값은 문자열로 비교되어 예기치 않은 일치가 발생할 수 있으므로 첫 번째 줄을 건너뛰어야 합니다.
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found=1; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
참고: awk
둘 이상의 파일을 사용하여 스크립트를 호출하는 경우 종료 코드는 모든 파일에서 일치 항목이 발견되었음을 의미합니다. 이 find
명령은 한 번에 하나의 파일만 에 전달되므로 awk
여기서는 문제가 되지 않습니다.
두 번째 편집:
일치하는 행이 2개 이상 있는 파일을 선택하려면 일치 항목을 계산하면 됩니다.
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found++; if(found >= 2) exit} END {exit found >= 2}' {} \; -exec mv -n {} ./NewFolder/ \;
편집하다:
스크립트가 열 4에 일치하는 값이 없는 파일을 이동하는 문제를 디버깅하려면 스크립트에 코드를 추가하여 awk
일치하는 줄에 대한 정보를 인쇄할 수 있습니다. 다음 코드는 일치하는 항목이 발견되면 파일 이름, 줄 번호 및 일치하는 줄을 인쇄합니다.
find . -type f -exec awk 'FNR==1 {next} $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
당신은 다음과 같은 것을 얻을 것입니다
threshold.txt:2:ABC DEF 5.10 0.94 GHI JKL
문제의 원인을 찾으려면 먼저 이 작업을 수행하는 것이 좋습니다.
4열에 숫자가 아닌 텍스트가 있는 줄이 있으면 값이 텍스트로 비교됩니다. 이는 예 "abc"
를 들어 "0.5"
.
또 다른 가능한 원인은 열 1이나 2에 공백이 있는 줄로 인해 열에 텍스트가 잘못 할당되는 경우일 수 있습니다.
열 4에 숫자가 아닌 값이 있고 이러한 줄을 무시하려는 경우 에서와 같이 값을 추가하여 숫자 해석을 강제할 수 0
있습니다 0 + $4
.
find . -type f -exec awk 'FNR==1 {next} 0 + $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
문제의 원인이 필드가 탭으로 구분되어 있고 해당 값에 공백이 포함될 수 있다는 것이라면 필드 구분 기호( -F "\t"
)를 지정할 수 있습니다. 다음 스크립트는 이를 다른 수정 사항과 결합합니다.
find . -type f -exec awk -F "\t" 'FNR==1 {next} 0 + $4 >= 0.5 {found=1; printf "%s:%d:%s\n", FILENAME, FNR, $0; exit} END {exit !found}' {} \; -exec mv -n {} ./NewFolder/ \;
답변2
실제로 는 작동하지 않습니다 . 문자열이 다음을 충족하기 awk
때문에 모든 파일을 찾습니다 .col4
>=0.5
$ echo col4 | awk '$1>=0.5'
col4
따라서 헤더를 건너뛰어야 합니다. 또한 파일이 기준과 일치하면 성공으로 종료하고 그렇지 않으면 실패로 종료하도록 awk에 지시해야 합니다. 이 같은:
find . -type f \
-exec awk -va=1 '{ if($4 >= 0.5 && NR>1){a=0}} END{exit a}' {} \; \
-exec mv -n {} ./NewFolder/ \;
답변3
for 루프를 사용하면 다음을 시도해 볼 수 있습니다.
for i in *; do # *.extension
[[ -f "$i" && $(awk 'NR>1 && $4 >= 0.5' "$i") ]] && mv "$i" NewFolder/
done
그리고 두 가지 값의 경우:
for i in *; do # *.extension
[[ -f "$i" ]] && [[ $(awk 'NR>1 && $4 >= 0.5' "$i" | wc -l) -ge 2 ]]
mv "$i" NewFolder
done