약 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.mp3
from 이 some_dir
로 이동되었지만 from 이 트리거되었습니다.mp3s
foo.mp3
another_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
$