파일을 한 단계 위로 이동하고 파일 이름 앞에 폴더 이름을 추가하시겠습니까?

파일을 한 단계 위로 이동하고 파일 이름 앞에 폴더 이름을 추가하시겠습니까?

테스트 환경:

  • ~ 에서 디렉토리를 생성 하고 ~ 0에서 ~까지의 9파일로 채웁니다.az
    $ 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

관련 정보