정규식의 역참조 "이름 바꾸기"

정규식의 역참조 "이름 바꾸기"

내 디렉토리에 "bar_foo.txt"라는 파일이 많이 있는데 이름을 "foo_bar.txt"로 바꾸고 싶습니다.

에서 정규 표현식은 교체의 역참조 검색과 유사 sed합니다 .vim's/\(bar\)_\(foo\)/\2_\1/g'

  1. 이를 수행할 수 있는 방법이 있습니까 rename? 파이프 ls로 연결할 수 있는 몇 가지 해킹을 본 적이 있지만 분명히 놀라운 접근 방식 sedbash아닙니다.

  2. 이를 수행할 수 있는 다른 도구가 있습니까?

  3. 정규식의 "sed 및 vim 스타일"에 이름이 있습니까?

답변1

renamePerl 정규식 구현을 사용하는 경우 (예: Debian/Ubuntu/... 또는 prenameArch Linux) $1또한 \1대괄호는 백슬래시 없이 캡처됩니다.

rename 's/(.*)_(.*)/$2_$1/' *_*

그렇지 않다면 직접 구현해야 합니다.

#! /bin/bash
for file in *_* ; do
    left=${file%_*}
    right=${file##*_}
    mv "$file" "$right"_"$left"
done

a_b_c참고: 작성된 대로 두 명령의 이름이 로 바뀌었습니다 c_a_b. get 을 수행하려면 b_c_a첫 번째 캡처 그룹을 .*?(첫 번째 경우)로 변경하거나 두 번째 경우 첫 번째 캡처 그룹을 %%%로 변경합니다 ##.#

답변2

이를 수행하기 위한 표준 도구는 다음과 같습니다 pax. 하지만 직접 이동하는 것보다 하드 링크와 복사본을 사용하는 것이 더 잘 작동합니다. 물론 모든 작업은 기본적으로 새 링크를 생성하고 이전 링크를 삭제합니다.

나는 단계에서 벗어나는 것을 선호합니다. 지금은 비교하고 대조할 동일한 트리의 복사본 두 개가 있습니다. 이는 파일 이름을 동적으로 바꿀 때 특히 중요합니다. 파일 이름에 대한 편집 작업의 결과는 기존 링크 이름과 동일할 수 있습니다. 이 경우 어떤 파일이 해당 이름을 갖게 됩니까?

따라서 POSIXly로 수행하려면 다음을 수행합니다.

pax -rwls'|^\(bar\)_\(foo\).txt$|\2_\1.txt|' -s'|.*||' *_*.txt .

완료되면 관련 파일에 대한 개별 링크가 생성됩니다. 결과가 요구사항과 일치하는지 확인하고 이전 결과를 삭제하십시오.

또한 정규식 스타일이 표준입니다 sed.vim갈아 바수다

답변3

  1. 와 함께유틸리티Linuxrename, 아니요, 이것은 기본적인 문자열 교체만 수행합니다. Perl 기반의 경우 rename예, 다음을 참조하세요.조 로바의 답변.

  2. zsh 사용zmv:

    autoload -U zmv      # put this in your ~/.zshrc
    zmv '(*)_(*).(*)' '${2}_$1.$3'
    zmv -w '*_*.*' '${2}_$1.$3'
    

    위의 두 호출은 zmv동일합니다. 하위 디렉터리에서 작업을 수행하려면 다음을 사용할 수 있습니다.zmv -w '**/*_*.*' '$1/${3}_$2.$4'

  3. Vi(m) 및 sed(확장) 사용기본 정규식. 당신은 또한 볼 수 있습니다내 정규 표현식이 X에서는 작동하지만 Y에서는 작동하지 않는 이유는 무엇입니까?

관련 정보