약 7,000개의 음악 파일이 포함된 디렉토리가 있습니다. 나는 Lame을 사용하여 그 안에 있는 모든 파일을 별도의 디렉터리에 재귀적으로 기록하여 동일한 상대 경로와 파일 이름을 가진 모든 파일을 출력했습니다. 출력 파일의 확장자는 .mp3이지만 일부 입력 파일의 확장자는 다릅니다(.wma, .aac 등).
출력 디렉터리에 약 100개 파일이 누락된 파일 수 차이를 볼 수 있습니다. 내가 원하는 것은 두 디렉터리를 비교하여 소스에는 있지만 대상에는 없는 파일 목록을 얻는 것입니다. 파일 확장자의 차이를 무시해야 한다는 점을 제외하면 이는 간단합니다.
테스트 실행을 켠 상태에서 rsync를 사용해 보았지만 파일 확장자를 무시하는 방법을 찾을 수 없습니다. 또한 diff를 시도했지만 이름으로만 확인하고 파일 확장자를 무시하는 옵션을 찾을 수 없습니다. 두 디렉터리 모두에서 재귀 ls를 수행하고 파일 확장자를 제거한 다음 출력을 비교할 수 있다고 생각하기 시작했지만 sed 또는 awk를 사용하여 ls 출력을 수정하는 작업부터 시작해야 할지 모르겠습니다.
답변1
목록을 보려면 하위 디렉터리로 반복되는 것과 그렇지 않은 것의 두 가지 변형이 있습니다. 모두 bash, ksh 및 zsh와 관련된 구문을 사용합니다.
comm -3 <(cd source && find -type f | sed 's/\.[^.]*$//' | sort) \
<(cd dest && find -type f | sed 's/\.[^.]*$//' | sort)
comm -3 <(cd source && for x in *; do printf '%s\n' "${x%.*}"; done | sort) \
<(cd dest && for x in *; do printf '%s\n' "${x%.*}"; done | sort)
zsh에서는 더 짧습니다.
comm -3 <(cd source && print -lr **/*(:r)) <(cd dest && print -lr **/*(:r))
comm -3 <(print -lr source/*(:t:r)) <(print -lr dest/*(:t:r))
이 명령은 두 파일( ) , 첫 번째 파일( )에만 또는 두 번째 파일( ) comm
에만 공통되는 줄을 나열합니다 . 이 숫자는 출력에서 뺀 내용을 나타냅니다. 두 개의 입력 파일을 정렬해야 합니다.comm -12
comm -23
comm -13
여기서 파일은 실제로 명령의 출력입니다. 쉘은 <(…)
"가짜" 파일(FIFO 또는 /dev/fd/
명명된 파일 설명자)을 명령에 대한 인수로 제공하여 이 구성을 평가합니다.
1 그래서 여기마이너스 스피커완벽하게 이해됩니다.
파일에 대한 작업을 수행하려면 소스 파일을 반복해야 할 수도 있습니다.
cd source
for x in *; do
set -- "…/dest/${x%.*}".*
if [ $# -eq 1 ] && ! [ -e "$1" ]; then
echo "$x has not been converted"
elif [ $# -gt 1 ]; then
echo "$x has been converted to more than one output file: " "$@"
else
echo "$x has been converted to $1"
fi
done