짧은 파일 이름 차이를 실행하는 방법은 무엇입니까?

짧은 파일 이름 차이를 실행하는 방법은 무엇입니까?

나는 bash 쉘을 사용하고 있습니다. 두 디렉터리의 파일 이름 차이를 확인하고 싶지만 해당 디렉터리의 직접 하위 디렉터리만 확인하고 싶습니다. 예를 들어, 다음과 같은 하위 파일/디렉토리가 있는 디렉토리가 있는 경우...

dir1
-> abc
-> def
-> ghi

dir2
-> abc
-> fff
-> ghi

dir2에는 dir1에는 없는 "fff"라는 이름의 파일/디렉토리가 있고 "dir1"에는 dir2에는 없는 "def"라는 하위 파일/디렉토리가 있음을 알려주는 일부 명령을 실행할 수 있기를 원합니다. 어떻게 해야 하나요?

답변1

for name in dir1/* dir2/*; do
    bname=${name##*/}

    if [ ! -e "dir1/$bname" ]; then
        printf '"%s" not in dir1\n' "$bname"
    elif [ ! -e "dir2/$bname" ]; then
        printf '"%s" not in dir2\n' "$bname"
    fi
done

이것은 dir1sum 의 모든 이름을 반복합니다 dir2. 경로 없이 $bname이름의 기본 이름이 됩니다 .$name

(기본) 이름이 에서 발견되지 않으면 dir1보고됩니다 . 그렇지 않으면 dir2보고서에서 찾을 수 없습니다.

이것은 삽입된 개행 문자가 포함된 파일 이름을 처리할 수 있으며 /bin/sh호환되는 모든 sh쉘에서 실행되어야 합니다.

이는 두 개 이상의 디렉터리로 확장될 수 있습니다. 그리고 bash:

dirs=( dir1 dir2 dir3 dir4 )

for dir in "${dirs[@]}"; do
    for name in "$dir"/*; do

        bname=${name##*/}

        for tdir in "${dirs[@]}"; do
            if [ ! -e "$tdir/$bname" ]; then
                printf '"%s" not found in %s\n' "$bname" "$tdir"
            fi
        done

    done
done

$ tree
.
|-- dir1
|   `-- filename 1
|-- dir2
|   |-- filename 1
|   |-- filename 3
|   `-- hello
world
`-- script.sh

$ sh script.sh
"filename 3" not in dir1
"hello
world" not in dir1

답변2

이를 위해 나는 comm -3plain 의 출력을 정말 좋아합니다 ls.

$ comm -3 <(ls dir1) <(ls dir2)
def
        fff

첫 번째 열의 항목은 첫 번째 디렉터리에만 있고, 두 번째 열의 항목은 두 번째 디렉터리에만 있습니다. 이 -3옵션은 두 디렉터리 모두에 공통된 항목을 표시하는 세 번째 열을 제거합니다. 또한 존재하지만 에 없는 파일 -1만 보거나 에 존재 하지만 존재하지 않는 파일 만 보도록 지정할 수도 있습니다 .dir2dir1-2dir1dir2

ls이렇게 하려면 옵션이 설정되어 있지 않은지 확인해야 합니다.통과하다해당 OPTIONS구성 또는 별칭입니다. 다음과 같은 변형을 사용하면 이러한 문제를 피할 수 있습니다.

$ comm -z -3 <(cd dir1; printf "%s\0" *) <(cd dir2; printf "%s\0" *) | tr '\0' '\n'
def
        fff

후자는 파일 이름의 특수 문자 문제를 방지합니다. -1이를 또는 와 결합하여 내부에 -2놓아 trxargs -0파일 세트 중 하나를 추가로 처리할 수 있습니다.

관련 정보