Bash는 주어진 확장자와 일치하지 않는 모든 파일을 복사합니다.

Bash는 주어진 확장자와 일치하지 않는 모든 파일을 복사합니다.

Shotwell의 카메라에서 사진을 가져오면 비디오 클립도 가져옵니다. 영상을 다른 폴더에 저장하고 싶어서 이게 좀 귀찮네요. 나는 성공하지 못한 채 이 작업을 수행하기 위해 bash 명령을 작성해 보았습니다.

다음 요구 사항을 충족하는 명령이 필요합니다.

  • .jpg, .png, .gif 또는 .xcf 확장자(대소문자 구분 안 함)가 있는 디렉터리 구조의 모든 파일을 찾습니다.
  • 파일 이름이나 디렉터리 경로에 공백이나 특수 문자가 포함되어 있는지 여부에 관계없이 이러한 모든 파일을 대상 디렉터리로 이동합니다.

어떤 도움이라도 대단히 감사하겠습니다!

편집: Ubuntu에서 기본 셸을 사용하고 있습니다. 이는 일부 명령에 별칭이 지정됨을 의미합니다.

편집 2: 제가 직접 시도했습니다(복사 부분이 아니라 파일 목록 부분만). extglob을 열고 다음 명령을 실행합니다.

$ ls -R /path | awk '
  /:$/&&f{s=$0;f=0}
  /:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
  NF&&f{ print s"/"$0 }'

여기에는 모든 것이 나열됩니다. 마지막에 grep을 사용해 보았지만 내가 준 패턴과 일치하지 않게 만드는 방법을 모르겠습니다. extglob 스위치는 grep에는 별로 도움이 되지 않지만 다른 명령에는 도움이 됩니다.

답변1

당신은 그것을 사용할 수 있습니다find일부 특정 테스트와 일치하는(또는 일치하지 않는) 디렉터리 트리의 모든 파일을 찾은 다음 해당 파일에 대해 몇 가지 작업을 수행합니다. 이 특정 문제의 경우 다음을 사용할 수 있습니다.

find -type f ! \( -iname '*.png' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.xcf' \) -exec echo mv {} /new/path \;

이렇게 하면 검색이 일반 파일( -type f)로 제한되고 !이름( )에 대소문자 확장자( ) 또는 ( )가 없는 파일 등으로 제한됩니다. 모든 확장은 단일 조건으로 그룹화됩니다. 일치하는 각 파일에 대해 파일을 디렉터리로 이동하는 명령( )을 실행하고 대신 파일 이름이 디렉터리에 삽입됩니다. 명령이 종료되었음을 나타냅니다.*.png-iname '*.png'-o*.gif\( ... \)-exec{}/new/path\;find

이름 대체는 프로그램 실행 코드 내에서 발생하므로 공백 및 기타 특수 문자는 중요하지 않습니다.


Bash에서 이 작업을 수행하려면 Bash의확장된 패턴 일치 기능. 이것들도 shopt extglob켜져 야 합니다 globstar. 이 경우 다음을 사용하십시오.

mv **/!(*.[gG][iI][fF]|*.[pP][nN][gG]|*.[xX][cC][fF]|*.[jJ][pP][gG]) /new/path

이는 대소문자 조합에서 , 등이 일치하지 않는 하위 디렉토리( )의 모든 파일을 일치시키고 해당 파일을 새 경로로 이동합니다 **. 확장은 셸에서 수행되므로 공백과 특수 문자는 더 이상 중요하지 않습니다.*.gif*.png

위의 내용은 모든 파일이 하위 디렉터리에 있다고 가정합니다. 그렇지 않은 경우 이후 섹션을 반복하여 **/현재 디렉터리를 포함할 수 있습니다.

비슷한 기능을 사용할 수 있습니다zsh및 기타 쉘을 사용하지만 Bash를 사용하고 있다고 표시했습니다.


(추가 참고 사항: 구문 분석은 ls결코 좋은 생각이 아닙니다. 시도하지 마세요.)

답변2

Ubuntu를 사용하므로 GNU를 찾을 수 있습니다. 다음을 시도해 보십시오.

find . -maxdepth 1 ! -iregex ".*\.\(jpg\|png\|gif\|xcf\)$" -exec mv -- -t /path/to/newdir "{}" +
  • -iregex정규식을 사용하여 파일 이름을 찾습니다. 단, 대소문자를 구분하지 않으며 !정규식을 무효화합니다.

  • -exec command +파일 일치 명령을 실행합니다. find -print0와 함께 사용하는 것과 같습니다 xargs -0. 이 기능을 사용하면 하나의 명령으로 찾은 여러 파일을 이동할 수 있으므로 mv호출된 총 명령 수가 일치하는 파일 수보다 적습니다.

  • -maxdepth 1검색을 현재 디렉터리로만 제한하고 find, 재귀적으로 사용하려면 제거하세요.

답변3

너무 복잡하게 만들 필요는 없습니다! 왜 안되나요:

mkdir ../temp
mv  *.{jpg,png,gif,xcf} ../temp/
mv * /desired/target/directory/
mv ../temp/* .
rmdir ../temp

물론 이는 전체 디렉터리 트리에서는 작동하지 않고 플랫 파일 디렉터리에서만 작동합니다.

관련 정보