노트

노트

파일이 포함된 일부 하위 디렉터리가 있는 디렉터리가 있습니다. 매우 유사한 하위 디렉터리가 있는 다른 디렉터리가 있지만 일부 하위 디렉터리가 추가되거나 제거되었을 수 있습니다. 두 디렉터리가 동일한 구조를 갖도록 하위 디렉터리를 어떻게 추가하고 제거할 수 있습니까?

명령이나 도구를 사용하여 이 작업을 수행하는 쉬운 방법이 있습니까? 아니면 각 하위 디렉터리를 검색하고 일치하는 하위 디렉터리가 있는지 확인하는 등 더 복잡한 작업을 수행해야 합니까?

답변1

이 답변을 위해 다음 도구를 사용했습니다.

  • 불다
  • comm
  • find
  • xargs

NUL로 구분된 레코드를 처리할 수 있으므로 마지막 3개 유틸리티의 GNU 버전을 사용하는 것이 좋습니다.

먼저 몇 가지 변수를 선언합니다. 디렉토리를 여러 번 변경하므로 이러한 모든 변수에 절대 경로 이름을 사용해야 합니다.

# The directories that will be compared
original_dir='/path/to/original/directory'
copy_dir='/path/to/copy/directory'

# Text files where we will save the structure of both directories
original_structure="${HOME}/original_structure.txt"
copy_structure="${HOME}/copy_structure.txt"

# Text files where we will separate each subdirectory
# depending on the action we will perform on them
dirs_to_add="${HOME}/dirs_to_add.txt"
dirs_to_remove="${HOME}/dirs_to_remove.txt"

두 디렉터리의 현재 구조를 저장합니다.

cd -- "${original_dir}"
find . \! -name '.' -type 'd' -print0 | sort -z > "${original_structure}"

cd -- "${copy_dir}"
find . \! -name '.' -type 'd' -print0 | sort -z > "${copy_structure}"

두 구조의 차이점을 저장합니다.

comm -23 -z -- "${original_structure}" "${copy_structure}" > "${dirs_to_add}"
comm -13 -z -- "${original_structure}" "${copy_structure}" > "${dirs_to_remove}"

누락된 디렉터리를 만듭니다.

cd -- "${copy_dir}"
xargs -0 mkdir -p -- < "${dirs_to_add}"

불필요한 디렉터리를 삭제합니다.

cd -- "${copy_dir}"
xargs -0 rm -rf -- < "${dirs_to_remove}"

임시 정보를 보관하기 위해 만든 텍스트 파일을 삭제합니다.

rm -- "${original_structure}" "${copy_structure}"
rm -- "${dirs_to_add}" "${dirs_to_remove}"

노트

  • 이 방법은 구조만 복사합니다. 소유자, 사용 권한 또는 속성은 유지되지 않습니다. 예를 들어 다른 도구를 사용하면 저장할 수 있다는 내용을 읽었 rsync지만 사용해 본 경험이 없습니다.

  • 위 코드를 스크립트에 넣으려면 오류 처리를 구현해야 합니다. 예를 들어, cd디렉토리 입력에 실패하고 잘못된 디렉토리에서 작동하면 재앙적인 결과를 초래할 수 있습니다.

답변2

이와 같은 쉘 함수는 다음을 수행할 수 있습니다.

comparedirs() (
    cd -- "${1?}";
    for d in */; do
        ! [ -d ../"${2?}"/"$d" ] && printf "%s\n" "$d is in '$1' but not in '$2'"
    done
)

시험:

$ mkdir -p left/{a,b,c}
$ mkdir -p right/{a,c,d}
$ comparedirs left right
b/ is in 'left' but not in 'right'
$ comparedirs right left
d/ is in 'right' but not in 'left'

../name이는 파일이 아닌 하위 디렉터리만 살펴보고 이러한 디렉터리가 실제로 형제라고 가정합니다 . 즉, .

관련 정보