내가 찾고 있어요두 줄의 이름 바꾸기내 음악 라이브러리를 관리해 보세요.
첫 번째걱정하다파일 이름. 가능한 가장 간단한 이름을 사용하고 싶습니다. 예 %track %title.ext
: 01 Song name.mp3
13 Song title.flac
etc. 나는 현재 파일의 구분 기호(트랙 번호와 노래 제목 사이)로 하이픈을 사용하는데, 이는 중복된다고 생각합니다.
두번째걱정하다폴더 이름, 좀 바꿔야겠어요무늬
From GENRE - Styles - ARTIST - Album (Year)
to GENRE - Styles - ARTIST - Year Album
(연도 전환 및 앨범 부분도 괄호 생략)
(저는 openbsd를 실행합니다.크쉬 88.)
그것은 내가 만들어낸 가장 가까운 선입니다.파일 이름사례:
for f in * ; do mv "$f" "$(print "$f" | sed "s/ - / /")" ; done
하지만 아직 작동하지 않았습니다. 나는 이것이 명령의 두 번째 인수(대상)를 올바르게 캡슐화하는 것과 관련이 있다고 생각합니다 mv
(편집하다: 따옴표를 추가하면 $( ... )
작동하지만 예상하지 못했습니다)
$pwd
/home/media/E - Chanson Française/CHANSON - Chanson Française - CHARLES TRENET - Le meilleur de Charles Trenet
$l -1
01 - Boum!.flac
02 - La route enchantée.flac
03 - Ah! Dis, Ah! Dis, Ah! Bonjour!.flac
04 - La vie qui va.flac
05 - Quand j'etais p'tit.flac
06 - Ménilmontant.flac
07 - Tout me sourit.flac
08 - Le oiseaux de Paris.flac
...
$for f in * ; do mv "$f" "$(print "$f" | sed 's/ - / /')" ; done
$l -1
01 Boum!.flac
02 La route enchantée.flac
03 Ah! Dis, Ah! Dis, Ah! Bonjour!.flac
04 La vie qui va.flac
05 Quand j'etais p'tit.flac
06 Ménilmontant.flac
07 Tout me sourit.flac
08 Le oiseaux de Paris.flac
...
큰따옴표를 중첩하면 오류가 발생할 것이라고 생각했지만 작동합니다. 이로써 첫 번째 사건은 해결됐다.
이것폴더 이름그 사건은 나를 더욱 피하게 만들었다. 다음은 변경하려는 이름의 예입니다.
$ ls -1
...
ELECTRO - Cyberpunk - CARPENTER BRUT - Blood Machines (2020)
ELECTRO - Cyberpunk - CARPENTER BRUT - Leather Teeth (2018)
ELECTRO - Cyberpunk - CARPENTER BRUT - Leather Terror (2022)
ELECTRO - Cyberpunk - CARPENTER BRUT - Trilogy (2015)
...
REGGAE - Roots - GROUNDATION - Each One Teach One (2001)
REGGAE - Roots - GROUNDATION - Hebron Gate (2002)
REGGAE - Roots - GROUNDATION - Upon the Bridge (2006)
REGGAE - Roots - GROUNDATION - Young Tree (1999)
...
결과는 다음과 같아야 합니다.
$ ls -1
...
ELECTRO - Cyberpunk - CARPENTER BRUT - 2015 Trilogy
ELECTRO - Cyberpunk - CARPENTER BRUT - 2018 Leather Teeth
ELECTRO - Cyberpunk - CARPENTER BRUT - 2020 Blood Machines
ELECTRO - Cyberpunk - CARPENTER BRUT - 2022 Leather Terror
...
REGGAE - Roots - GROUNDATION - 1999 Young Tree
REGGAE - Roots - GROUNDATION - 2001 Each One Teach One
REGGAE - Roots - GROUNDATION - 2002 Hebron Gate
REGGAE - Roots - GROUNDATION - 2006 Upon the Bridge
...
필드를 전환하려면 awk를 사용해야 할 것 같습니다. for f in *CARPENTER\ BRUT* ; do mv "$f" "$( print "$f" | awk ... )" ; done
마지막 하이픈 다음 연도를 awk로 전환하고 tr로 대괄호를 제거할 수도 있지만 이를 배우는 데 어려움을 겪고 있습니다.
답변1
zsh를 설치할 수 있는 경우:
XX - title.flac
일반 파일 에XX title.flac
.zsh <<\EOF autoload zmv zmv -n '(**/)(<-> )- (*.(#i)(ogg|mp3|flac))(#q.)' '$1$2$3' < /dev/tty EOF
GENRE - Styles - ARTIST - Album (Year)
GENRE - Styles - ARTIST - Year Album
디렉토리 로zsh <<\EOF autoload zmv zmv -n '(**/)(* - * - * - )(*) \((<->)\)(#q/)' '$1$2$4 $3' < /dev/tty EOF
만족스러우면 삭제 -n
(테스트 실행)합니다.
zsh를 설치할 수 없는 경우 find
and를 사용 perl
하면 다음과 같은 결과를 얻을 수 있습니다.
XX - title.flac
XX title.flac
일반 파일 로LC_ALL=C find . -depth -name '[0-9]*.*' -type f -print0 | perl -l -0ne ' ($dir, $base) = m{^(.*/)(.*)\z}s; if ($base =~ s/^(\d+ )- (.*\.(?i:ogg|mp3|flac))\z/$1$2/s) { print qq(rename($_, "$dir$base")) or warn "$_: $!"; }'
GENRE - Styles - ARTIST - Album (Year)
GENRE - Styles - ARTIST - Year Album
디렉토리 로LC_ALL=C find . -depth -name '*(*)' -type d -print0 | perl -l -0ne ' ($dir, $base) = m{^(.*/)(.*)\z}s; if ($base =~ s/( - .* - .* - )(.*) \((\d+)\)\z/$1$3 $2/is) { print qq(rename($_, "$dir$base")) or warn "$_: $!"; }'
그리고 만족스러우면 print qq(...)
주변을 삭제하세요.rename()
하지만 주목할 점은 다음과 같습니다.
- 또한 숨겨진 파일/디렉토리(및 숨겨진 디렉터리 내)도 처리합니다.
- 보호 기능이 없으므로
zmv
결국 기존 파일을 덮어쓸 수 있습니다.
OpenBSD의 ksh 및 기본 POSIX 유틸리티를 사용하여 이를 수행하는 것이 가능하지만 매우 투박합니다.
가능한:
XX - title.flac
일반 파일 에XX title.flac
.LC_ALL=C find . -depth -name '[0-9][0-9] - *' '(' \ -name '*.[Ff][Ll][Aa][Cc]' -o \ -name '*.[Oo][Gg][Gg]' -o \ -name '*.[Mm][Pp]3' ')' -type f -exec ksh -c ' for file do dir=${file%/*} base=${file##*/} print -r mv -i -- "$file" "$dir/${base%% *}${base#* -}" done' {} +
GENRE - Styles - ARTIST - Album (Year)
GENRE - Styles - ARTIST - Year Album
디렉토리 로LC_ALL=C find . -depth -name '* - * - * - * (*[0-9])' -type d -exec ksh -c ' for file do dir=${file%/*} base=${file##*/} if [[ $base = *" ("+([0-9])")" ]]; then album="${base##* - }" year=${album##*\(} year=${year%\)} base=${base%"$album"} album=${album%" ("*} print -r mv -i -- "$file" "$dir/$base$year $album" fi done' {} +
( 만족스러우면 삭제하세요 print -r
).
해당 방법과 perl
동일한 주의 사항이 있지만 -i
전달된 옵션은 데이터 손실을 방지 하는 mv
데 도움이 됩니다(대신mv
이동하다도착하다이사 오다대상 파일이 존재하고 디렉토리 유형인 경우).
귀하의 시도와 관련하여 :
sed
텍스트 유틸리티이고 줄 기반이며 파일 경로에 단일 텍스트 줄은 물론 텍스트가 포함된다는 보장이 없으므로 파일 이름에 대한 파일 경로를 처리하지 않는 것이 가장 좋습니다.print
, 기본적으로 옵션을 허용하는 많은 구현과 마찬가지로echo
(OpenBSD의 ksh 구현에서는 그렇지 않은 것처럼 보이지만 일부는 임의 명령이 실행될 수 있음) 일부 백슬래시 이스케이프 시퀀스 확장을 수행합니다. 텍스트를 축어적으로 출력하려면(유효한 행에서 끝나도록 개행 문자 다음에), 특히 로 시작하지 않을 것이라고 보장할 수 없는 경우에는print -r - "$text"
또는 이 필요합니다 .print -r -- "$text"
$text
-
- 명령( )을 따옴표 없이 바꾸면
$(...)
결과에 결국 분할+glob이 적용됩니다. 네, 인용하셔도 됩니다. 중첩된 참조는 더 이상 사용되지 않는 명령 대체 형식을 사용하는 경우에만 문제가 되지만`...`
, 그럴 경우에도 가능합니다cmd1 "`other-cmd \" $var \"`"
. . $(...)
삭제 조심하세요모두후행 개행으로 인해 일반적으로 너무 많은 항목을 제거하게 됩니다.--
mv
그런 다음 그는 사라졌습니다.mv
sed
파일 경로를 수정하지 않고도 호출 이 됩니다.- OpenBSD의 ksh 에서
for i in *
현재 작업 디렉터리에 숨겨지지 않은 파일이 없으면 루프에*
파일 이름으로 경로가 계속 남게 됩니다. 일치하지 않는 파일에 대한 오류가 보고zsh
됩니다 .zmv
- oksh glob을 사용할 때 파일 유형(예: zsh의
(#q.)
===-type f
및(#q/)
===-type d
)에 따라 glob 확장을 제한할 수 없습니다. - 위의 방법과 달리 현재 작업 디렉터리의 파일 이름만 바꾸므로 각 디렉터리에서 프로세스를 반복해야 합니다.