정규식과 일치하는 하위 디렉토리를 재귀 적으로 이름 바꾸기


11

폴더가라는 미디어 서버가 Series있습니다. ( /media/Expansion2/Series/)

그것에, (놀람!) TV 시리즈가 있습니다. 예를 들어 쇼 이름 일뿐입니다./media/Expansion2/Series/The Big Bang Theory/

각 쇼의 폴더 안에 (그리고 이것이 문제가있는 곳입니다) 계절 폴더가 있습니다. 현재 다음 두 가지 규칙이 혼합되어 있습니다 (아마도 몇 가지 더 있음).

  1. /media/Expansion2/Series/The Big Bang Theory/The Big Bang Theory Season 1
  2. /media/Expansion2/Series/The Big Bang Theory/Season 2

결국 모든 폴더의 이름을로 바꾸고 싶습니다 Season #.

정규식으로, 아마도 다음과 같이 말할 것입니다. s/.*(Season \d)/$1

파일이 아닌 폴더에만 적용됩니다. 나는 또한 이것이 약 50 + 쇼 하위 폴더에 대한 것이라고 언급해야하므로 /media/Expansion2/Series/레벨 에서 시작 하여 각 시리즈를 살펴 봐야합니다. :)

답변:


12

데비안 및 파생 상품 (우분투 포함) :

find /media/Expansion2/Series/ -type d -exec rename -n 's/.*(Season \d)/$1/' {} ";"

rename명령은 Perl 패키지의 일부입니다. 다른 배포판에서는 제공되지 않지만 대신 표준 Linux rename명령을 제공합니다 .

만약 rename -n(-not 정말) 디스플레이가하고 싶어하고 당신을 위해 모든 오른쪽 -n을 생략하고 그렇게 할 무엇.


필자는이 방법이 지난 며칠 동안 특히 폴더뿐만 아니라 파일에도 유용하다는 것을 알았습니다. 감사.
Denham Coote

1
내가 기억하는 한,이 도구는 rename데비안 에서만 호출 됩니다 . 우분투 (및 일부 맛)에서 이전에 언급 한 표준 rename명령 과 이름 충돌을 피하기 위해 때때로 (항상 그런 것은 아님)에서 찾을 수 prename있습니다. 여기서 Lubuntu에서는 도구 자체가 호출 prename되지만 renamesymlink chain 으로 인해 호출 될 수 있습니다 /usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-rename. 여기서 file-rename약간 수정 된 버전이 prename있습니다.
syntaxerror

대박! 여러 디렉토리의 여러 파일에 대해 그렇게했습니다!
eusoubrasileiro

2

다음 스 니펫은 Season [0-9]의 모든 show 디렉토리에서 마지막으로 발생하기 전에 발생하는 모든 내용을 제거합니다 /media/Expansion2/Series. 정규 표현식이 필요하지 않고 단지 globs입니다.

cd /media/Expansion2/Series
for show in ./*/; do
    (
        cd "$show" || { echo "cd failed.  Skipping $show"; exit 1; }
        for season in ./*Season\ [[:digit:]]*/; do
                season_prefix=${season%Season [[:digit:]]*}
                mv "$season" ./"${season#$season_prefix}"
        done
    )
done

2

당신이 그것을 안전하게 재생하고 이름 some show/some show stuff을 바꾸 려면 some show/stuff:

for d in */; do
  for f in "$d${d%/} *"; do
    mv "$f" "${d}${f%$d${d%/} }"
  done
done

전에 모든 것을 제거하려면 Season다음을 수행하십시오.

for x in */*Season*; do
  mv "$x" "${x%/*}/${x##*Season}Season"
done

${var#PATTERN}시작 부분에서 PATTERN을 제거 $var하고 결과를 반환합니다. ${var%PATTERN}마지막에 동일하게 수행합니다. ${var#PATTERN}${var%PATTERN}최단 매칭 프리픽스 및 서 픽스를 각각 제거; ${var##PATTERN}그리고 ${var%%PATTERN}가장 긴 일치를 제거합니다.


0

앞으로 도움이 될 수 있기를 바랍니다. 이들은 직장에서 리눅스 관리자로부터 온 것입니다. 이 손톱에 얼마나 많은 망치가 작동하는지 보여주십시오!

해결책 1 :

안녕 덴햄,

예를 들어 "XXX Season #"을 가진 디렉토리의 일부는 항상 "외부"디렉토리 (리프 노드)가 될 것이라고 가정합니다.

어쨌든 작은 스크립트를 작성합니다. 이와 같은 것이 작동해야합니다 (디렉토리의 모든 공간을 캡처하려면 변수 주위에 큰 따옴표를 유의하십시오).

find /media/Expansion2/Series/ -type d | while read olddir
do 
   newdir=`echo "${olddir}" | awk -F "/" '$NF ~ /Season/ { last=substr($NF,index($NF, "Season")); while (i<(NF-1)) { i++; printf("/%s", $i) }; printf("/%s\n", last) } $NF !~ /Season/ { print }'`
   if [ "${olddir}" != "${newdir}" ]
   then
       mv "${olddir}" "${newdir}"
   fi
done

물론, "mv"$ {olddir} ""$ {newdir} ""명령으로 실행하기 전에 "echo"$ {olddir} ""$ {newdir} ""과 같은 것을 넣어야합니다. 예상 한 결과를 얻거나 다른 두통으로 끝날 수 있습니다 :-P


해결책 2 :

안녕 덴햄,

대부분의 답변은 이미 문제에있었습니다. 어쨌든 Series 폴더에서 다음과 같은 것을 실행하면 정상적으로 작동합니다.

find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "`dirname "$dir"`/`basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i"`"; done  


설명 :
• find -mindepth 2 -maxdepth 2-타입 d (디렉토리를 두 ​​레벨 아래로 나열)
• dir을 읽는 동안; (각 디렉토리에 루프)
• mv -T "$ dir"(소스 디렉토리를 다음으로 이동 : -T는 계절 폴더가 고유하지 않은 경우 오류가 발생하는 데 필요합니다. 즉 "빅뱅 이론 시즌이없는 경우" 동일한 디렉토리의 22 "및"Season 22 ")
• dirname"$ dir "은 dir이있는 경로를 반환합니다.
• basename"$ dir "은 디렉토리의 이름을 반환합니다
. • sed"s /. Season ([0-9] ) $ / Season \ 1 / i "는 대소 문자를 구분하지 않는 정규 표현식으로 마술을 완성합니다.

내 작은 테스트에서 효과가있었습니다 (mv 전에 에코로 먼저 시도하십시오).

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/The Big Bang Theory Season 1
./The Big Bang Theory/The Big Bang Theory Season 1/file1.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file 3.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file2.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file
./The Big Bang Theory/The Big Bang Theory Season 1/3.avi
./Other Series
./Other Series/Season 2
./Other Series/Stre dsfdf sd dSeason 3

someuser@linux-box:/tmp/Series$ find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "dirname "$dir"/basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i""; done
mv: ./The Big Bang Theory/Season 2' and./The Big Bang Theory/Season 2' are the same file
mv: ./Other Series/Season 2' and./Other Series/Season 2' are the same file

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/Season 1
./The Big Bang Theory/Season 1/file1.avi
./The Big Bang Theory/Season 1/file 3.avi
./The Big Bang Theory/Season 1/file2.avi
./The Big Bang Theory/Season 1/file
./The Big Bang Theory/Season 1/3.avi
./Other Series
./Other Series/Season 3
./Other Series/Season 2

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.