저는 Mac을 사용하고 있기 때문에 mv는 약간 다르며 해당 --backup
속성을 지원하지 않습니다. 제가 생각해 낼 수 있는 최선의 방법은 다음과 같습니다.
find . -mindepth 2 -type f -print -exec mv {} . \;
답변1
몇 가지 스크립트를 작성해야 합니다. 그것은 다음과 같습니다:
find . -mindepth 2 -type f -print | while read x; do
y=$(basename "$x")
if [ -f "$y" ]; then
mv "$y" "$y".backup
fi
mv "$x" "$y"
done
답변2
mv
디렉토리가 아닌 경우 target 명령의 단순 백업을 생성하려면 다음을 수행하십시오 .
if [ -e "$target" ] && [ ! -d "$target" ]; then
mv "$target" "$target.backup"
fi
$target.backup
기존 디렉토리라면 분명히 바람직하지 않은 결과를 초래할 것입니다. 또한 기존 항목이 $target.backup
있으면 덮어씁니다.
열거 백업 구성표를 사용하는 것이 더 안전합니다.
mv
디렉토리가 아닌 경우 target 명령의 열거 백업을 생성하려면 다음을 수행하십시오 .
suffix=1
if [ -e "$target" ] && [ ! -d "$target" ]; then
while [ -e "$target.$suffix" ]; do
suffix=$(( suffix + 1 ))
done
mv "$target" "$target.$suffix"
fi
그러면 $target
파일 이름을 사용하지 않게 $target.N
만드는 첫 번째 양의 정수 이름이 변경됩니다 .N
$target.N
하지만 여기에는 경쟁 조건이 있다는 점에 유의하세요.다른이 코드의 인스턴스(또는 완전히 관련되지 않은 프로세스)는 $target.$suffix
이름이 사용되지 않음을 감지하고 $target
해당 이름으로 이동하는 사이에 생성될 수 있습니다.
이를 방지하려면:
suffix=1
if [ -e "$target" ] && [ ! -d "$target" ]; then
while [ -d "$target.$suffix" ] ||
! ln "$target" "$target.$suffix" 2>/dev/null; do
suffix=$(( suffix + 1 ))
done
fi
ln
이제 우리는새 이름(하드 링크) $target
.의 경우 기존 디렉토리의 이름을 생성하는 정수도 건너뜁니다. 무료 새 이름을 찾을 때까지 이 작업은 실패합니다.
그럼 당신은 할 수 있습니다
mv "$source" "$target"
find
이전과 마찬가지로 모든 일반 파일을 이동 하려면 다음 명령을 적용하세요 .
find . -mindepth 2 -type f -print -exec sh -c '
for source do
target=${source##*/}
suffix=1
if [ -e "$target" ] && [ ! -d "$target" ]; then
while [ -d "$target.$suffix" ] ||
! ln "$target" "$target.$suffix" 2>/dev/null; do
suffix=$(( suffix + 1 ))
done
fi
mv "$source" "$target"
done' sh {} +
시험:
$ tree
.
|-- dir1
| `-- file
|-- dir2
| `-- file
`-- dir3
`-- file
3 directories, 3 files
$ # the find command goes here
./dir1/file
./dir2/file
./dir3/file
$ tree
.
|-- dir1
|-- dir2
|-- dir3
|-- file
|-- file.1
`-- file.2
3 directories, 3 files
이 예에서는 가장 최근에 찾은 파일, 이전에 찾은 파일, 첫 번째로 찾은 파일이 file
됩니다 .file
file.2
file.1
find
불행하게도 macOS에서의 구현은 mv -n
사용 가능한 종료 상태를 반환하지 않습니다. 실행 실패 시 0이 아닌 값이 반환되면 mv
더 적은 경쟁 조건을 사용하여 더 간단한 방법으로 문제를 해결할 수 있습니다.
답변3
이것이 내 최종 결과입니다.
num=1
find . -mindepth 2 -type f -print | while read x; do
y=$(basename "$x")
if [ -f "$y" ]; then
mv "$y" "$y"."$num"
num=$(( $num + 1 ))
fi
mv "$x" "$y"
done
따라서 .backup을 사용하지 마십시오. 동일한 이름을 가진 다른 백업이 있으면 여전히 발생할 수 있습니다. 영감을 주셔서 감사합니다!