디렉토리 구조를 평면화하려면 다음을 수행하십시오.
find . -type f -exec sh -c 'mv "{}" "./`basename "{}"`"' \;
내 프로필에 다음을 저장하고 싶습니다: $FLATTEN
-exec sh -c 'mv "{}" "./`basename "{}"`"' \;
이렇게 하면 나중에 실행할 수 있습니다.find . $FLATTEN
너무 일찍 해석되어 변수를 저장하는 데 문제가 있습니다. 문자열 리터럴로 저장하고 가져올 때가 아닌 셸에서 사용될 때만 해석되기를 원합니다.
답변1
GNU를 사용한다면 mv
다음과 같이 해야 합니다:
find . -type f -exec mv -t . {} +
다른 사람 mv
:
find . -type f -exec sh -c 'exec mv "$@" .' sh {} +
{}
코드를 삽입하면 안 됩니다 sh
. 이는 파일 이름이 쉘 코드( `reboot`
예: 이름이 지정된 파일을 사용하려는 시도) 로 해석되기 때문에 명령 주입 취약점입니다 .
quote 명령 대체는 좋은 점이지만 고대 형식( `...`
대신 $(...)
)을 사용하고 있으므로 내부 큰따옴표 또는sh
Bourne Shell 또는 AT&T ksh 기반 구현 에서는 작동하지 않습니다.(실제로는 불일치 "`basename "foo bar"`"
(이 쉘에서는 허용됨 )로 간주된 다음 연결됩니다)."`basename "
`
foo
bar"`"
또한 다음을 수행할 때:
mv foo/bar bar
bar
존재하고 디렉토리라면 실제로는 디렉토리입니다 . mv foo/bar bar/bar
그렇지 mv -t . foo/bar
않으면 mv foo/bar .
그런 문제가 없습니다.
이제 이러한 몇 가지 매개변수(,,,,,,,)를 변수에 저장하려면 -exec
배열 변수가 필요합니다. 배열을 지원하는 셸에는 , , , , , , 등이 있습니다.sh
-c
exec mv "$@" .
sh
{}
+
(t)csh
ksh
bash
zsh
rc
es
yash
fish
ksh/bash/yash 또는 가 $FLATTEN
아닌 변수를 직접 사용할 수 있으려면 합리적인 배열 구현을 갖춘 쉘이 필요합니다 : 또는 . 또한 여기서는 이러한 매개변수 중 비어 있는 것이 없습니다."${FLATTEN[@]}"
$FLATTEN:q
(t)csh
rc
es
fish
zsh
존재하다 rc
/ es
/ zsh
:
FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)
존재하다 fish
:
set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +
그런 다음 다음을 사용할 수 있습니다.
find . -type f $FLATTEN
답변2
이를 달성하고 올바른 결과를 얻으려면 쉘 함수를 사용하는 것이 더 좋습니다 ( 하위 쉘 -exec
에 넣지 마십시오 ).{}
flatten () {
( cd "${1:-.}" &&
find . -type f -exec sh -c 'for n; do test -e "${n##*/}" || mv "$n" "${n##*/}"; done' sh {} + )
}
또한 외부 유틸리티를 호출할 필요가 없으며 basename
이미 존재하는 것을 덮어쓰려고 시도하지도 않습니다.
이를 사용하기 위해 입력하면 flatten
현재 디렉토리에서 작동합니다. 디렉터리 이름을 지정하면 해당 디렉터리가 실행됩니다(해당 디렉터리 아래의 모든 파일을 해당 디렉터리의 맨 위로 복사).
답변3
함수가 아마도 가장 좋은 방법일 것입니다. 그렇지 않으면 배열이 필요하거나 다음이 필요합니다 eval
.
find_array=(-exec sh -c 'mv "{}" "./`basename "{}"`"' \;)
find . "${find_array[@]}"
또는
FLATTEN="-exec sh -c 'mv \"{}\" \"./`basename \"{}\"`\"' \;"
eval find . $FLATTEN
답변4
기능은 어떻습니까?
flatten(){
find "$@" -type f -exec sh -c 'mv -- "$0" "${0##*/}"' {} \;
}
용법:
> flatten .
사용하시면 선택 zsh
하실 수 있습니다 . 이를 통해 명령 이름뿐만 아니라 전역적으로 삽입되는 별칭을 정의할 수 있습니다.-g
alias