파이프에서 디렉토리로 모든 파일을 이동하는 방법은 무엇입니까?

파이프에서 디렉토리로 모든 파일을 이동하는 방법은 무엇입니까?

데스크탑 디렉토리의 모든 요소에 대해 file 명령을 실행했습니다.

~/Desktop > file * 

그런 다음 설명에 "image"라는 문자열이 포함된 모든 줄을 검색합니다.

~/Desktop > file * | grep "image"

그런 다음 각 줄에서 파일 이름을 제거합니다.

~/Desktop> file * | grep "image" | cut -d: -f1

이 단계에서는 얻은 모든 파일 이름을 디렉토리로 이동하는 방법을 모르겠습니다. xargs를 시도했지만 잘못 이해한 것 같습니다.

~/Desktop> file * | grep "image" | cut -d: -f1 | xargs mv {} ./dirk

답변1

--target-directory옵션 보기mv

답변2

{}xargs더 이상 사용되지 않는 -i옵션을 전달하거나 -I {}.

file * | grep "image" | cut -d: -f1 | xargs -I {} mv {} ./dirk

이는 파일 이름에 특수 문자( :\"'또는 개행이나 이니셜 -, 공백이 사용됨 xargs -I)가 포함되지 않은 경우에만 작동합니다. 여기에는 images이미지가 아니더라도 파일 이름 도 포함됩니다 . 여기에는 file그림의 이미지뿐만 아니라 "디스크 이미지"와 같이 명령이 "이미지"로 설명하는 파일이 포함됩니다.

콘텐츠가 이미지인 파일을 필터링하는 보다 안정적이지만 완벽하지는 않은 방법은 file -i로 설명된 파일을 사용하고 찾는 것입니다. 아래 코드 조각은 일부 버전의 ¹을 혼동할 수 있는 따옴표 문자도 변환합니다.FILENAME: image/TYPExargs

file -i ./* |
sed -n -e 's/["'\''\\]/\\&/' -e 's/: *image\/[^:]*$//p' |
xargs -I {} mv {} ./dirk

최신 버전의 GNU 유틸리티(즉, 내장되지 않은 Linux 시스템 또는 Cygwin)에서는 빈으로 구분된 목록을 사용하여 처리를 안정적이고 약간 더 빠르게 만들 수 있습니다.

file -0i ./* |
sed -z -e 's/: *image\/[^:]*$//p' |
xargs -0 mv -t ./dirk

대안은 루프를 사용하거나 파일을 반복하는 것입니다. file *이는 명령줄 길이 제한으로 인해 실패하더라도 작동합니다.find

for x in ./*; do
  if [ -n "$(file -i "$x" | sed -n '$/: *image\/[^:]*$/ p')" ]; then
    mv "$x" ./dirk
  fi
done

1 POSIX는 인용 처리가 비활성화되었음을 의미 하지만 4.4.2 현재 findutils의 GNU 버전에서는 그렇지 않습니다.-Ixargs

관련 정보