특정 열의 임의 행에서 임계값보다 높은 값을 가진 파일을 이동합니다.

특정 열의 임의 행에서 임계값보다 높은 값을 가진 파일을 이동합니다.

특정 폴더에 많은 수의 파일이 있습니다. 4열의 행에 0.5보다 큰 값이 하나 이상 있는 경우 이 파일을 하위 폴더로 이동하고 싶습니다. 별도의 명령으로 동일한 작업을 수행하고 싶지만 파일의 0.5 열 4에 위 값이 있는 행이 2개 이상 있어야 합니다.

다음은 파일의 일반적인 형식입니다(헤더 포함).

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 이상의 값이 1개 이상 있는 파일을 이동하려는 시도입니다. 결국 기준과 일치하지 않는 파일이라도 모든 파일을 하위 폴더로 이동하게 됩니다.

#!/bin/bash

find . -type f -exec awk '$4 >= 0.5' {} \; -exec mv -n {} ./NewFolder/ \;

답변1

명령이 제대로 작동하려면 일치하는 항목이 있으면 코드 0으로 종료해야 하고 awk, 일치하는 항목이 없으면 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

관련 정보