테스트 환경:
- ~ 에서 디렉토리를 생성 하고 ~
0
에서 ~까지의9
파일로 채웁니다.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