sed를 사용하여 파일 이름 대량 변경
객관적으로
다음 파일 이름을 변경합니다.
- F00001-0708-RG-biasliyda
- F00001-0708-CS-각들
- F00001-0708-VF-hioulgigl
다음 파일 이름으로:
- F0001-0708-RG-biasliyda
- F0001-0708-CS-각들
- F0001-0708-VF-hioulgigl
셸 코드
테스트 대상:
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/
저는 모르겠어요.
먼저, 가장 쉬운 방법은 frename 또는 rename 명령을 사용하는 것입니다.
Ubuntu, 패키지 Ubuntu(홈브루) OSX)에서rename
패키지 MacPorts 파일p5-file-rename
이름이 된 다른 Perl 파일 이름:
rename s/0000/000/ F0000*
또는 RHEL과 같이 util-linux-ng에서 이름이 변경된 시스템에서.
rename 0000 000 F0000*
이는 동등한 sed 명령보다 훨씬 더 이해할 수 있습니다.
하지만 sed 명령어를 이해하는 것에 대해서는 sed man 페이지가 도움이 됩니다.maned를 실행하고 &을 검색하면 (/명령어를 사용하여 검색) s/foo/bar/replacements의 특수 문자임을 알 수 있습니다.
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
.
은 대문자은다사음모여든것결다합을니합하용을체열▁puts▁it▁를 사용하여 모든 것을 한데 .&
파일 이름)및 (원래및일이름) 파\1\2
으로, 165 문 자 (0) 제 외 파 모 부 니 다 입 분 든 이 름 의 일 째 한 를 두 니 다 , ▁which 입 nd ▁the ▁except ▁is 0 ▁a ▁character ▁of ▁every ▁part ▁filename ▁2 분부
이것은 꽤나 난해한 방법입니다, IMHO.어떤 이유로 rename 명령을 사용할 수 없고 이름을 변경하는 데 에 사용하려는 경우(또는 이름을 바꾸기 위해 너무 복잡한 작업을 수행하는 경우) 정규식에서 더 명시적으로 지정하면 훨씬 더 읽기 쉬워집니다.아마도 다음과 같은 것이 있을 것입니다.
ls F00001-0708-*|sed 's/F0000\(.*\)/mv & F000\1/' | sh
s/search/replacement에서 실제로 무엇이 변경되고 있는지를 확인할 수 있기 때문에/ 훨씬 더 읽기 쉽습니다.또한 실수로 파일 이름을 두 번 이상 실행해도 파일 이름에서 문자를 계속 빨아들이지 않습니다.
당신은 설명을 들었습니다. 이제 셸만 사용할 수 있습니다. 외부 명령이 필요 없습니다.
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\
) 에서 그런다음대텍에서다같음수사있이용습다니할과스트체▁them▁in다있▁as로 사용할 수 \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
마커가 그것을 조금 바꿉니다.
검색 문자열은 시작할 때 단일 문자와 일치하며, 그 다음에 단일 문자가 오고 나머지 문자열(패턴 2로 기억됨)이 옵니다.
교체 문자열에서 이러한 일치 패턴을 참조하여 교체의 일부로 사용할 수 있습니다.전체 일치 부분을 다음과 같이 참조할 수도 있습니다.&
.
그래서 그게 뭐죠?sed
중인 은 다음과 같습니다.: " "mv
원본 파일(소스용)과 문자 1 및 3 이상을 기반으로 하는 명령으로, 문자 2(대상용)를 효과적으로 제거합니다.다음 형식을 따라 일련의 줄이 표시됩니다.
mv F00001-0708-RG-biasliuyda F0001-0708-RG-biasliuyda
mv abcdef acdef
등등.
perl 이름 변경 사용(도구 상자에 있어야 함):
rename -n 's/0000/000/' F0000*
제다한을 합니다.-n
출력 이름을 실제로 변경하기에 적합할 때 전환합니다.
이 작업을 수행할 수도 있고 수행할 수도 없는 동일한 이름의 다른 도구도 있으므로 주의하십시오.
rename 명령어 이름 util-linux
꾸러미, 하지 마.
명령을 :GNU
)
$ rename
은 다시피보를 봅니다.perlexpr
그렇다면 이것이 올바른 도구인 것 같습니다.
그렇지 그지않 일기설로정으값본우적됨(보통은 해당.Debian
그고파 같물은 것생리 것은▁like와 같은 파생물.Ubuntu
:
$ sudo apt install rename
$ sudo update-alternatives --set rename /usr/bin/file-rename
archlinux의 경우:
pacman -S perl-rename
Red Hat 계열 디스트리뷰터의 경우:
yum install prename
'프리네임' 패키지는 EPEL 저장소에 있습니다.
Gentoo의 경우:
emerge dev-perl/rename
*BSD의 경우:
pkg install gprename
또는p5-File-Rename
Mac 사용자의 경우:
brew install rename
다른 배포자와 함께 이 명령을 사용하지 않는 경우 패키지 관리자를 검색하여 설치하거나 수동으로 수행합니다.
cpan -i File::Rename
이전 독립 실행형 버전은 여기에서 찾을 수 있습니다.
이 도구는 원래 Perl의 아버지인 Larry Wall에 의해 작성되었습니다.
백슬래시-모음(backslash-parent)은 "패턴을 일치시키는 동안 여기에 일치하는 것을 유지하라"는 의미입니다. 나중에 대체 텍스트 쪽에서 기억된 조각들을 "\1"(첫 번째 괄호 안에 있는 블록), "\2"(두 번째 블록) 등으로 되돌릴 수 있습니다.
실제로 두 번째 문자를 제거하는 것이 무엇이든 상관없이 다음과 같은 작업을 수행할 수 있습니다.
s/.//2
하지만 당신의 명령은 그것을 구축하는 것입니다.mv
명령을 내리고 실행을 위해 셸에 파이프를 연결합니다.
이것은 당신의 버전보다 더 읽을 수 없습니다.
find -type f | sed -n 'h;s/.//4;x;s/^/mv /;G;s/\n/ /g;p' | sh
네 번째 문자는 다음 이유로 제거됩니다.find
각 파일 이름 앞에 "/."를 붙입니다.
제가 할 일은 다음과 같습니다.
for file in *.[Jj][Pp][Gg] ;do
echo mv -vi \"$file\" `jhead $file|
grep Date|
cut -b 16-|
sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done
그런 다음 문제가 없으면 추가합니다.| sh
끝까지그래서:
for file in *.[Jj][Pp][Gg] ;do
echo mv -vi \"$file\" `jhead $file|
grep Date|
cut -b 16-|
sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done | sh
for i in *; do mv $i $(echo $i|sed 's/AAA/BBB/'); done
괄호는 백슬래시 숫자에서 사용할 특정 문자열을 캡처합니다.
ls F00001-0708-*|sed 's|^F0000\(.*\)|mv & F000\1|' | bash
저에게 맞는 몇 가지 예는 다음과 같습니다.
$ tree -L 1 -F .
.
├── A.Show.2020.1400MB.txt
└── Some Show S01E01 the Loreming.txt
0 directories, 2 files
## remove "1400MB" (I: ignore case) ...
$ for f in *; do mv 2>/dev/null -v "$f" "`echo $f | sed -r 's/.[0-9]{1,}mb//I'`"; done;
renamed 'A.Show.2020.1400MB.txt' -> 'A.Show.2020.txt'
## change "S01E01 the" to "S01E01 The"
## \U& : change (here: regex-selected) text to uppercase;
## note also: no need here for `\1` in that regex expression
$ for f in *; do mv 2>/dev/null "$f" "`echo $f | sed -r "s/([0-9] [a-z])/\U&/"`"; done
$ tree -L 1 -F .
.
├── A.Show.2020.txt
└── Some Show S01E01 The Loreming.txt
0 directories, 2 files
$
2>/dev/null
외부 출력을 억제합니다(예: ...).참조 [이 스레드]:https://stackoverflow.com/a/2372808/1904943
변경 사례: https://www.networkworld.com/article/3529409/converting-between-uppercase-and-lowercase-on-the-linux-command-line.html
언급URL : https://stackoverflow.com/questions/2372719/using-sed-to-mass-rename-files
'bestsource' 카테고리의 다른 글
Mongodb - 조건부인 경우 집계 $push (0) | 2023.05.24 |
---|---|
Azure의 새 스토리지 계정과 기존 스토리지 계정의 차이점 (0) | 2023.05.24 |
어떤 분기에서 문자열을 도입한 Git 커밋을 어떻게 찾을 수 있습니까? (0) | 2023.05.24 |
mongoid에서 embeds_many와 has_many의 차이 (0) | 2023.05.14 |
WPF 탭 항목 머리글 스타일 (0) | 2023.05.14 |