Linux 환경에서 실행될 스크립트를 작성하려고 합니다.
.jpeg
디렉토리 트리에서 파일을 찾아 이름이 지정된 디렉토리에 복사합니다 jpegs
.
중복된 파일 이름을 표시하고 싶지만 오류만 표시하는 대신 생성된 목록에 중복된 파일 이름을 한 번만 나열하여 동일한 이름을 두 번 표시하지 않습니다.
이것은 지금까지 내 스크립트입니다.
#!/bin/sh
if ! mkdir jpegs 2> /dev/null
then
echo " Cannot create directory \"jpegs\" perhaps it already exists."
echo " delete the directory and try again."
exit
fi
for srcpath in $(find fs282/mirror -iname "*.jpg")
do
cp --backup $srcpath jpegs/
done
echo "List of Duplicate Files Follows"
답변1
출력을 반복하지 마십시오 find
. 이는 우아하지 않으며(루프는 모든 경로 이름을 찾을 때까지 첫 번째 반복을 시작하지 않음) 위험합니다(발견된 경로 이름은 공백, 탭 및 줄 바꿈으로 분할되며 쉘은 파일 이름 와일드카드 패턴으로 확장하려고 시도합니다).
대신(이름 충돌이 있는 경우 발견된 파일을 복사하지 않으려는 것으로 가정합니다):
find fs282/mirror -type f -iname '*.jpeg' -exec sh -c '
for pathname do
if [ -e "jpegs/${pathname##*/}" ]; then
printf "%s\n" "${pathname##*/}"
else
cp "$pathname" jpegs/
fi
done' sh {} + | sort -u
find
인라인 쉘 스크립트의 경로 이름 생성기 로 사용됩니다 . find
발견된 경로 이름은 스크립트에 전달되고 .NET의 각 경로 이름을 사용하여 해당 경로 이름을 반복합니다 $pathname
. 이 스크립트는 경로 이름의 파일 이름 부분이 디렉토리에 있는지 테스트하고 jpegs
, 그렇다면 경로 이름 끝에 파일 이름을 표준 출력으로 인쇄합니다. 파일 이름이 없으면 jpegs
파일이 복사됩니다.
매개변수 대체는 ${pathname##*/}
처음부터 $pathname
마지막까지 문자를 제거합니다 /
. ] 끝에 있는 파일 이름 부분을 제외하고.
마지막으로 sort -u
인라인 스크립트로 인쇄된 모든 파일 이름을 가져와서 중복을 제거하면서 정렬합니다.
또 다른 방법:
find fs282/mirror -type f -iname '*.jpeg' \
! -exec sh -c '[ -e "jpegs/${1##*/}" ] && printf "%s\n" "${1##*/}"' sh {} ';' \
-exec cp {} jpegs ';' | sort -u
본질적으로 동일한 내용이지만 완전히 다르게 표현됩니다.
짧은 인라인 셸 스크립트를 사용하여 파일 이름이 아래에 있는지 테스트하고 jpegs
, 그렇다면 파일 이름을 인쇄하고 나중에 정렬한 후 find
다음 파일로 진행합니다. 존재하지 않는 경우 파일이 복사됩니다.
관련된: