나는 주어진 이름을 가진 모든 디렉토리를 찾는 방법을 알고 있습니다.
find . -name unnecessary_dir_level
파일을 상위 디렉터리로 이동하는 방법은 다음과 같습니다.
mv * ..
어떻게 결합하나요? - 예
find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;
혼란을 일으키지 않고 이 작업을 완료하고 싶습니까? 아니면 어떻게 될까요? 나는 조언 없이 이것을 시도하고 싶지 않습니다(그리고 디렉토리가 너무 커서 합리적인 시간에 백업할 수 없습니다).
답변1
(계속 중단되지 않는) 옵션을 지원하는 구현을 사용하면 zsh
다음을 수행할 수 있습니다.mv
-n
for dir (**/unnecessary_dir_level(ND/od)) () {
(( ! $# )) || mv -n -- $@ $dir:h/ && rmdir -- $dir
} $dir/*(ND)
어디:
for var (values) cmd
루프의 짧은 버전입니다(프로그래밍 언어에서 더 일반적임)for
.**/
: 전역 연산자, 즉모든 수준의 하위 디렉터리N
glob 한정자:nullglob
이 glob을 활성화합니다(일치하는 항목이 없어도 불평하지 마세요).D
glob 한정자:dotglob
이 glob을 활성화합니다(숨겨진 파일 포함)./
glob 한정자: 파일 형식으로 제한됨목차.od
glob 한정자:o
rder byd
epth(해당 분기 이전에 나옴)() { body; } args
: 매개변수가 있는 익명 함수입니다.- 여기매개변수존재
$dir/*(ND)
: 숨김 파일을 포함한 모든 파일$dir
- 이것몸이러한 파일(있는 경우)에 대해 실행한 다음
mv
이제 비어 있어야 하는rmdir
파일에 대해 실행합니다 .$dir
$dir:h
, (csh와 같은 디렉토리 이름)h
.$dir
다음 mv * ..
두 계정은 잘못되었습니다.
- 옵션 구분 기호가 누락되었습니다.
mv -- * ..
- 숨겨진 파일이 누락되었습니다:
mv -- *(D) ..
zsh, ((shopt -s nullglob failglob; exec mv -- * ..)
inbash
) - 또한: 상위 파일에 같은 이름의 파일이 있으면 데이터가 손실될 수 있습니다.
find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;
{}/*
glob이 호출되기 전에 쉘에 의해 확장되기 때문에 작동하지 않습니다 mv
. 현재 디렉터리에 호출 디렉터리가 있으면 다른 디렉터리로 확장된 다음 {}
잘못된 파일이 이동됩니다.
find
다음 과 같이 bash
비슷한 작업을 수행 할 수 있습니다 .
find . -depth -name unnecessary_dir_level -type d -exec \
bash -O nullglob -O dotglob -c '
for dir do
set -- "$dir"/*
(( ! $# )) || mv -n -- "$@" "${dir%/*}" && rmdir -- "$dir"
done' bash {} +
답변2
버전 bash
>= 4.0:
shopt -s globstar nullglob dotglob
for f in **/name/; do echo mv "$f"* "$f"..; done
출력이 괜찮아 보이면 삭제하세요 echo
.
에서 man bash
:
globstar
: 설정된 경우 경로 이름 확장 컨텍스트에 사용된 패턴 **은 모든 파일과 0개 이상의 디렉터리 및 하위 디렉터리와 일치합니다. 패턴 뒤에 /가 오면 디렉터리와 하위 디렉터리만 일치합니다.
nullglob
: 설정된 경우 bash는 파일 [...]과 일치하지 않는 패턴이 자체가 아닌 빈 문자열로 확장되도록 허용합니다.
dotglob
: 설정된 경우 bash는 경로 이름 확장 결과에 "."로 시작하는 파일 이름을 포함합니다.
답변3
for loop
를 사용하여 발견된 각 디렉터리의 내용을 이전 수준으로 이동할 수 있습니다 . 예를 들어, 내 디렉토리 temp
에 파일이 있습니다 abc
.
tmp/abc/
└── temp
다음 명령이 디렉토리 temp
에 배치됩니다 tmp
.
for i in ` find . -name abc ` ; do mv $i/* $i/.. ; done