"find -exec mv"에 4개의 파일이 없습니다.

"find -exec mv"에 4개의 파일이 없습니다.

약 1000개의 mp3 파일을 복잡하게 중첩된 디렉터리 구조를 포함하는 "music"이라는 디렉터리에서 "mp3s"라는 단일 디렉터리로 이동하여 차에서 해당 파일을 들을 수 있도록 하고 싶습니다.

내가 사용하는 명령은 다음과 같습니다

find music -name '*mp3' -exec mv -v -t mp3s {} +

그런데 명령어를 실행하니 이상한 현상이 발생합니다. 명령이 완료된 후 4개의 파일이 생략된 것을 확인했습니다. 이러한 파일은 다음과 같습니다.

"music/Michael Hedges/Michael Hedges - Taproot/06 - Chava's Song.mp3"
'music/Michael Hedges/Michael Hedges - Aerial Boundaries/04 - Ragamuffin.mp3'
'music/Jonas Hellborg/1988 - Bass/07. Blues For LW.flac.mp3'
'music/Jonas Hellborg/1988 - Axis/03. Roman.flac.mp3'

나는 똑같은 명령을 다시 실행했고 이번에는 이전에 생략된 4개의 파일이 예상대로 이동되었습니다.

find왜 그런 예상치 못한 일이 일어날지 상상할 수 없습니다 . 왜 이런 일이 발생합니까?

우분투의 bash 쉘에서 실행됩니다.

답변1

가정: 이름 충돌

어느 시점에서 명령이 다음과 같이 보였다고 상상해 보십시오.

mv -v -t mp3s … …/some_dir/foo.mp3 … …/another_dir/foo.mp3 …

foo.mp3from 이 some_dir로 이동되었지만 from 이 트리거되었습니다.mp3sfoo.mp3another_dir

mv: will not overwrite just created 'mp3s/foo.mp3' with '…/another_dir/foo.mp3'

분명히 메시지 그룹에서 메시지가 눈에 띄지 않게 되었습니다 -v.

나중에 두 번째가 find다시 이동하려고 시도했지만 …/another_dir/foo.mp3이번에는 이동하지 않았 …/some_dir/foo.mp3으므로 mp3s/foo.mp3"방금 생성된" 것으로 간주되지 않고 덮어썼습니다.

-exec mv … {} +둘 이상이 실행 중일 수도 있습니다 mv. …/some_dir/foo.mp3및가 …/another_dir/foo.mp3다른 통화에 할당된 경우 mv후자는 "방금 생성된" mv것으로 간주되지 않습니다 . mp3s/foo.mp3이는 귀하의 경우 이름 충돌이 더 많이 발생하고 일부 파일이 자동으로 덮어쓰여질 수 있음을 의미합니다. 이름 충돌 로 인해 동일한 기본 이름을 가진 파일이 동일한 이름에 할당된 경우에만 mv일부 파일을 이동할 수 없습니다 .


개념의 증거

$ mv --version
mv (GNU coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Parker, David MacKenzie, and Jim Meyering.
$
$ mkdir -p music/a music/b music/c mp3s
$ touch music/a/A music/b/B music/c/A
$ tree --noreport
.
|-- mp3s
`-- music
    |-- a
    |   `-- A
    |-- b
    |   `-- B
    `-- c
        `-- A
$ find music -type f -exec mv -v -t mp3s {} +
renamed 'music/a/A' -> 'mp3s/A'
renamed 'music/b/B' -> 'mp3s/B'
mv: will not overwrite just-created 'mp3s/A' with 'music/c/A'
$ tree --noreport
.
|-- mp3s
|   |-- A
|   `-- B
`-- music
    |-- a
    |-- b
    `-- c
        `-- A
$ find music -type f -exec mv -v -t mp3s {} +
renamed 'music/c/A' -> 'mp3s/A'
$ tree --noreport
.
|-- mp3s
|   |-- A
|   `-- B
`-- music
    |-- a
    |-- b
    `-- c
$ 

관련 정보