[bash] sed를 사용하여 파일 이름 바꾸기

객관적인

다음 파일 이름을 변경하십시오.

  • F00001-0708-RG-biasliuyda
  • F00001-0708-CS-akgdlaul
  • F00001-0708-VF- 히 울기 글

다음 파일 이름에 :

  • F0001-0708-RG-biasliuyda
  • F0001-0708-CS-akgdlaul
  • F0001-0708-VF- 히 울기 글

쉘 코드

테스트하려면 :

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/'

수행하려면 :

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/' | sh

내 질문

sed 코드를 이해하지 못합니다. 대체 명령이 무엇인지 이해합니다.

$ sed 's/something/mv'

방법. 그리고 정규 표현식을 다소 이해합니다. 그러나 나는 여기서 무슨 일이 일어나고 있는지 이해하지 못합니다.

\(.\).\(.*\)

또는 여기 :

& \1\2/

전자는 “단일 문자, 단일 문자, 단일 문자의 길이 시퀀스”를 의미하는 것처럼 보이지만 확실히 그 이상의 의미가 있습니다. 후반부까지 :

& \1\2/

나는 모른다.



답변

첫째,이를 수행하는 가장 쉬운 방법은 prename 또는 rename 명령을 사용하는 것입니다.

Ubuntu, OSX (Homebrew 패키지 rename, MacPorts 패키지 p5-file-rename) 또는 perl 이름 변경 (사전 이름)이있는 기타 시스템 :

rename s/0000/000/ F0000*

또는 RHEL과 같이 util-linux-ng에서 이름을 바꾸는 시스템 :

rename 0000 000 F0000*

동등한 sed 명령보다 훨씬 이해하기 쉽습니다.

그러나 sed 명령을 이해하려면 sed 맨 페이지가 도움이됩니다. man sed를 실행하고 &를 검색하면 (/ 명령을 사용하여 검색) s / foo / bar / 대체에서 특수 문자임을 알 수 있습니다.

  s/regexp/replacement/
         Attempt  to match regexp against the pattern space.  If success‐
         ful,  replace  that  portion  matched  with  replacement.    The
         replacement may contain the special character & to refer to that
         portion of the pattern space  which  matched,  and  the  special
         escapes  \1  through  \9  to refer to the corresponding matching
         sub-expressions in the regexp.

따라서에서 \(.\)참조 할 수있는 첫 번째 문자와 일치합니다 \1. 그런 .다음 항상 0 인 다음 문자 \(.*\)와 일치 합니다. 그런 다음에서 참조 할 수있는 나머지 파일 이름과 일치합니다 \2.

대체 문자열은 &(원래 파일 이름)을 사용하여 모든 것을 모으고 \1\2두 번째 문자 인 0을 제외한 파일 이름의 모든 부분입니다.

이것은 IMHO를 수행하는 꽤 비밀스러운 방법입니다. 어떤 이유로 rename 명령을 사용할 수없고 sed를 사용하여 이름을 변경하려는 경우 (또는 이름 바꾸기에 너무 복잡한 작업을 수행 했습니까?) 정규식에서 더 명시 적으로 지정하면 훨씬 더 읽기 쉽습니다. 아마도 다음과 같습니다.

ls F00001-0708-*|sed 's/F0000\(.*\)/mv & F000\1/' | sh

s / search / replacement /에서 실제로 변경되는 내용을 볼 수 있으면 훨씬 더 읽기 쉽습니다. 또한 실수로 두 번 또는 무언가를 실행하면 파일 이름에서 문자를 계속 빨아 들이지 않습니다.


답변

sed 설명을 마쳤습니다. 이제 셸만 사용할 수 있으며 외부 명령이 필요하지 않습니다.

for file in F0000*
do
    echo mv "$file" "${file/#F0000/F000}"
    # ${file/#F0000/F000} means replace the pattern that starts at beginning of string
done


답변

sed몇 년 전에 일괄 이름 변경에 대한 예제가 포함 된 작은 게시물을 작성했습니다 .

http://www.guyrutenberg.com/2009/01/12/batch-renaming-using-sed/

예를 들면 :

for i in *; do
  mv "$i" "`echo $i | sed "s/regex/replace_text/"`";
done

정규식에 그룹 (예 :)이 포함 \(subregex\된 경우 대체 텍스트 \1\에서 \2등 으로 사용할 수 있습니다 .


답변

가장 쉬운 방법은 다음과 같습니다.

for i in F00001*; do mv "$i" "${i/F00001/F0001}"; done

또는 이식 가능하게

for i in F00001*; do mv "$i" "F0001${i#F00001}"; done

이렇게 F00001하면 파일 이름 의 접두사가 F0001. mahesh에 대한 크레딧 : http://www.debian-administration.org/articles/150


답변

sed명령

s/\(.\).\(.*\)/mv & \1\2/

대체하는 의미 :

\(.\).\(.*\)

와:

mv & \1\2

일반 sed명령 과 같습니다 . 그러나 괄호 &\n마커는 약간 변경됩니다.

검색 문자열은 처음에 단일 문자와 일치하고 (패턴 1로 기억) 나머지 문자열이 뒤 따르는 단일 문자 (패턴 2로 기억 됨)가 뒤 따릅니다.

교체 문자열에서 이러한 일치 된 패턴을 참조하여 교체의 일부로 사용할 수 있습니다. 전체 일치 부분을 &.

따라서이 sed명령이 수행하는 작업은 mv원본 파일 (소스 용)과 문자 1 및 3을 기반으로 명령을 생성 하여 문자 2 (대상 용)를 효과적으로 제거하는 것입니다. 다음 형식에 따라 일련의 줄을 제공합니다.

mv F00001-0708-RG-biasliuyda F0001-0708-RG-biasliuyda
mv abcdef acdef

등등.


답변

backslash-paren 항목은 “패턴을 일치시키면서 여기에서 일치하는 항목을 붙잡 으십시오.”라는 의미입니다. 나중에 대체 텍스트 쪽에서 “\ 1″(첫 번째 괄호 안에있는 블록), “\ 2″(두 번째 블록) 등으로 기억 된 조각을 다시 가져올 수 있습니다.


답변

정말로하고있는 일이 두 번째 문자를 제거하는 것이라면 그것이 무엇이든 상관없이 다음과 같이 할 수 있습니다.

s/.//2

그러나 당신의 명령은 명령을 빌드하고 mv실행을 위해 쉘에 파이프합니다.

이것은 귀하의 버전보다 더 읽을 수 없습니다.

find -type f | sed -n 'h;s/.//4;x;s/^/mv /;G;s/\n/ /g;p' | sh

네 번째 문자는 find각 파일 이름 앞에 “./”가 붙기 때문에 제거됩니다 .