
테스트 환경:
0
to 부터 디렉토리를 만들고 to9
부터 파일로 채웁니다 .a
z
$ mkdir {0..9} && touch {0..9}/{a..z}
- 에 의한 결과
find
:$ find -type f ./0/a ./0/b ... ./9/y ./9/z
출력을 다음과 같이 변환하려면 어떻게 해야 합니까?
./0a
./0b
...
./9y
./9z
답변1
Perl의 독립 rename
실행형 명령을 사용하면:
rename -n 's|/||' */*
모든 것이 괜찮아 보이면 -n
나머지 빈 디렉터리를 제거한 다음 제거합니다.
rmdir {0..9}
답변2
POSIX 도구를 사용하면
find . -type f -exec sh -c 'for f; do dirn="${f%/*}"; mv -- "$f" "$dirn${f##*/}"; done' sh {} +
find
쉘을 호출하고 각 파일에 대해 for 루프를 실행합니다.
dirn="${f%/*}"
파일 이름에서 마지막 슬래시 뒤의 모든 항목을 제외하고 포함하여 상위 디렉터리 이름을 가져옵니다.${f##*/}
파일 이름의 마지막 슬래시 앞의 모든 항목을 제외하고 포함하여 경로 없이 파일 이름을 가져옵니다.
이 두 쉘 구성은 다음과 동일합니다.dirname
그리고basename
, 따라서 명령의 동등한 형식은 다음과 같습니다.
find . -type f -exec sh -c 'for f; do mv -- "$f" "$(dirname "$f")$(basename "$f")"; done' sh {} +
, 각 파일에 대해 두 개의 추가 프로세스를 생성해야 하므로 속도가 느려집니다.
예제에서 볼 수 있듯이 단일 디렉터리 이상으로 내려갈 필요가 없으면 간단한 셸 루프를 사용하면 됩니다.
for f in */*; do dirn="${f%/*}"; echo mv -- "$f" "$dirn${f##*/}"; done