특정 확장자를 가진 모든 파일에서 확장자를 반복적으로 제거합니다.

특정 확장자를 가진 모든 파일에서 확장자를 반복적으로 제거합니다.

그 안에 많은 하위 디렉토리가 있고 그 안에 많은 확장 기능이 있는 디렉토리가 있습니다 .no_sub.

.no_sub확장자를 가진 모든 파일의 이름을 같은 이름으로 바꾸고 .no_sub삭제하고 싶습니다 .

그래서 foo.no_sub-> foo.

Bash에서 이 작업을 수행할 수 있나요? (저는 우분투 20.04를 사용하고 있습니다)

답변1

표준 find, shmv:을 사용하십시오.

find . -type f -name '*.no_sub' -exec sh -c '
    for pathname do
        mv -- "$pathname" "${pathname%.no_sub}"
    done' sh {} +

.no_sub이름이 문자열로 끝나는 현재 디렉토리 안이나 아래의 일반 파일을 찾습니다. 이러한 경로 이름의 일괄 처리에 대해 짧은 인라인 쉘 스크립트가 호출됩니다. 이 sh -c스크립트는 주어진 경로 이름 배치를 반복하고 파일 이름 접미사를 제거하여 각각의 이름을 바꿉니다 .no_sub. 파일 이름 접미사 제거는 ${variable%suffix}표준 매개변수 확장을 사용하여 수행됩니다.

파일 이름 충돌은 확인되지 않습니다.

이것은비슷한도착하다Marcus Müller가 제공하는 솔루션개별 파일의 이름 바꾸기는 동일한 방식으로 발생하지만 find숨겨진 이름을 선택하고 일반 파일에 대해서만 반복하기 위해 명시적인 파일 유형 필터를 포함하는 방식으로 경로 이름의 루프 목록을 생성하는 데 사용됩니다.

또한보십시오:"find"의 -exec 옵션 이해


인라인 스크립트에 주어진 모든 파일 이름은 다음으로 끝난다는 것을 알고 있습니다 .no_sub..no_sub

find . -type f -name '*.no_sub' -exec sh -c '
    for pathname do
        mv -- "$pathname" "${pathname%.*}"
    done' sh {} +

답변2

셸의 기능을 사용하여 모든 파일을 가져온 다음 일반 도구를 사용하여 이름을 바꿉니다.

shopt -s nullglob ## as recommended and explained in the comments
shopt -s globstar
shopt -s dotglob
for fname in **/*.no_sub ; do
  mv -- "${fname}" "${fname%.no_sub}"
done

여기,

  • shopt -s globstar**재귀적 글로브로 활성화됨
  • shopt -s dotglob발견할 수 있는.*.no_sub
  • 루핑은 for모든 파일(절대 분석하지 ls마세요)
  • 구문 mvmv source target;
  • 가끔은 지나치게 조심스러울 때도 있지만, 단지 변수 이름에 혼동이 있어서는 안 되기 때문에 ${fname}그보다는 낫다는 점도 마음에 듭니다. 현재 파일인 $fname변수의 내용으로 확장됩니다 .fname
  • 변수 확장은 ${variable%pattern}변수 내용으로 확장되지만 접미사 패턴을 통해 축소됩니다.pattern

답변3

다음을 사용하여 find이 작업을 수행할 수 있습니다 xargs.

find . -name '*.nosub' -print0 | xargs -0 rename .nosub ""

옵션과 -print0옵션은 공백이 포함된 파일 이름을 올바르게 처리하는 데 사용됩니다. 이 명령은 소프트웨어 패키지에서 제공됩니다.find-0xargsrenameutil-linux

답변4

POSIX 사용 find:

find . -type f -name '*.no_sub' \
-exec perl -le '
  rename $_, s/\.no_sub$//r
    for @ARGV;
' {} +;

.no_sub이름이 로 끝나는 일반 파일을 찾습니다 perl.

그런 다음 Perl은 내장된 이름 바꾸기 명령을 호출하고 뒤에 오는 .no_sub 확장자를 제거하여 본질적으로 파일을 이동합니다.

관련 정보