[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
각 파일 이름 앞에 “./”가 붙기 때문에 제거됩니다 .