ProgramingTip

여러 파일을 찾아 Linux에서 이름

bestdevel 2020. 12. 10. 20:58
반응형

여러 파일을 찾아 Linux에서 이름


시스템 과 같은 파일 a_dbg.txt, b_dbg.txt ...Suse 10있습니다. 이 파일에서 "_dbg"를 제거하여 이름을 변경하는 bash 쉘 배포를 작성하고 싶습니다.

Google은 rename명령 을 사용 제안했습니다 . 명령을 실행 나는 그래서 rename _dbg.txt .txt *dbg*CURRENT_FOLDER

내 실제 CURRENT_FOLDER에는 아래에 파일이 포함되어 있습니다.

CURRENT_FOLDER/a_dbg.txt
CURRENT_FOLDER/b_dbg.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt

rename명령을 실행 한 후

CURRENT_FOLDER/a.txt
CURRENT_FOLDER/b.txt
CURRENT_FOLDER/XX/c_dbg.txt
CURRENT_FOLDER/YY/d_dbg.txt

재귀 적으로 수행하는 것이 모든 하위 디렉토리의 파일 이름을 바꾸는이 명령을 만드는 방법입니다. 좋아요 XX그리고 YY나는 이름을 예측할 수없는 너무 많은 하위 디렉토리를 찾을 것입니다. 또한 CURRENT_FOLDER다른 파일도 번 것입니다.


를 사용 find하여 일치하는 모든 파일을 재귀 적으로 사용할 수 있습니다 .

$ find . -iname "*dbg*" -exec rename _dbg.txt .txt '{}' \;

편집 : 무엇 '{}'이며 무엇 \;입니까?

-exec인수는 발견 된 rename모든 일치 여부 파일에 대해 를 실행 찾을 합니다. '{}'파일의 경로 이름으로 대체됩니다. 마지막 토큰 \;은 exec 요약의 끝을 표시하기위한 것입니다.

모든 것은 찾기에 대한 man 페이지에 잘 설명되어 있습니다.

 -exec utility [argument ...] ;
         True if the program named utility returns a zero value as its
         exit status.  Optional arguments may be passed to the utility.
         The expression must be terminated by a semicolon (``;'').  If you
         invoke find from a shell you may need to quote the semicolon if
         the shell would otherwise treat it as a control operator.  If the
         string ``{}'' appears anywhere in the utility name or the argu-
         ments it is replaced by the pathname of the current file.
         Utility will be executed from the directory from which find was
         executed.  Utility and arguments are not subject to the further
         expansion of shell patterns and constructs.

모든을 .txt 신뢰로 / tmp 및 하위 디렉토리 아래의 .cpp 서로 재귀 적으로 모두를 위해 파일 작은 펼쳐

#!/bin/bash

for file in $(find /tmp -name '*.txt')
do
  mv $file $(echo "$file" | sed -r 's|.txt|.cpp|g')
done

재귀 적으로 이름을 바꾸려면 다음 명령을 사용합니다.

find -iname \*.* | rename -v "s/ /-/g"


bash 사용 :

shopt -s globstar nullglob
rename _dbg.txt .txt **/*dbg*

위의 Scipt는 한 줄로 사용 가능합니다.

find /tmp -name "*.txt" -exec bash -c 'mv $0 $(echo "$0" | sed -r \"s|.txt|.cpp|g\")' '{}' \;

find -execdir rename 정규식으로 파일과 디렉토리의 이름을 바꾸려면

접미사를 사용하는 것이 아니라 정규식으로 파일과 디렉토리의 이름을 변경하려는 경우 다음이 좋은 패턴입니다.

find-rename-regex() (
  set -eu
  find_and_replace="$1"
  PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
    find . -depth -execdir rename "${2:--n}" "s/${find_and_replace}" '{}' \;
)

GitHub 업스트림 .

공백 ''을 하이픈 '-'으로 바꾸는 예제 사용. 드라 이런 :

find-rename-regex ' /-/g'

교체를 수행하십시오.

find-rename-regex ' /-/g' -v

awesome -execdir옵션은 명령을 cd실행하기 전에 .rename-exec

-depth 부모 디렉토리 누락으로 인한 잠재적 인 문제를 방지하기 위해 이름 변경이 먼저 자식에서 수행 된 다음 부모에서 발생하는지 확인합니다.

-execdir 이름이 기본 이름이 아닌 입력 경로에서 제대로 작동하지 않기 때문에 필요합니다. 예를 들면 다음과 같습니다.

rename 's/findme/replaceme/g' acc/acc

PATH때문에 해킹이 필요 -execdir하나 매우 짜증나는 단점이 find매우 독단적를하고 아무것도 할 거부 -execdir당신이 당신의 상대 경로가있는 경우 PATH예를 들어 환경 변수 ./node_modules/.bin와 실패를 :

find : 상대 경로 './node_modules/.bin'이 PATH 환경 변수에 포함되어 있으며 find의 -execdir 조치와 결합하여 안전하지 않습니다. $ PATH에서 해당 항목을 제거하십시오.

참조 : https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirPOSIX에 대한 GNU 찾기 확장 입니다. renamePerl 기반이며 rename패키지 에서 제공 됩니다.

미리보기 해결 방법 이름 바꾸기

입력 경로가에서 오지 find않거나 상대 경로가 충분히 불편하다면 Perl lookahead를 사용하여 다음과 같이 디렉토리 이름을 안전하게 바꿀 수 있습니다.

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

내가있는 편리한 아날로그를 발견하지 않았습니다 -execdirxargs: https://superuser.com/questions/893890/xargs-change-working-directory-to-file-path-before-executing/915686

sort -r더 이상 경로가 동일한 접두사와 짧은 사람 한 후 온 이후 파일이 각 디렉토리 이후에 올 수 있도록해야합니다.

Ubuntu 18.10에서 테스트되었습니다.


이름 만 바꾸고 외부 도구를 사용해도 괜찮다면 rnm 을 사용할 수 있습니다 . 명령은 다음과 같습니다.

#on current folder
rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' *

-dp -1 모든 하위 디렉토리에 대해 재귀 적으로 만듭니다.

-fo 파일 전용 모드를 의미합니다.

-ssf '_dbg' 파일 이름에 _dbg가있는 파일을 검색합니다.

-rs '/_dbg//' _dbg를 빈 문자열로 바꿉니다.

CURRENT_FOLDER의 경로로도 위의 명령을 실행할 수 있습니다.

rnm -dp -1 -fo -ssf '_dbg' -rs '/_dbg//' /path/to/the/directory

아래에서 사용할 수 있습니다.

rename --no-act 's/\.html$/\.php/' *.html */*.html

클래식 솔루션 :

for f in $(find . -name "*dbg*"); do mv $f $(echo $f | sed 's/_dbg//'); done

참고 URL : https://stackoverflow.com/questions/16541582/find-multiple-files-and-rename-them-in-linux

반응형