正規表現に一致するサブディレクトリの名前を繰り返し変更します。

正規表現に一致するサブディレクトリの名前を繰り返し変更します。

というフォルダがあるメディアサーバーがありますSeries。 ( /media/Expansion2/Series/)

そこには(驚くべきことに!)テレビシリーズがあります。これは単なるプログラム名です。/media/Expansion2/Series/The Big Bang Theory/

各ショーのフォルダ内に(それが問題です)シーズンフォルダがあります。私は現在、次の2つの規則(そしておそらく他の規則)を混在して使用しています。

  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/レベルから始めて各シリーズを確認する必要があります。 :)

答え1

Debianとその派生製品(Ubuntuを含む):

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

このrenameコマンドはPerlパッケージの一部です。他のディストリビューションは標準のLinuxコマンド以外には提供していませんが、renameここでは役に立ちません。

(-not true)が実行したい操作を表示し、rename -n問題が発生しない場合は、-nを省略してそのままにしてください。

答え2

次のコードは、Season [0-9]各ディスプレイディレクトリで最後に発生する前に発生したすべてのエントリを削除します/media/Expansion2/Series。正規表現は必要なく、単にglobです。

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

答え3

安全を保つには、名前を次のよう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}

答え4

2つのソリューションをさらに公開します。後で役立つことを願っています。これは職場のLinux管理者が提供したものです。この釘にどれだけのハンマーが届くかをお見せしましょう!

解決策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 -minlength 2 -max 深さ 2 -type d (ディレクトリを 2 レベル下にリストします)
• while read dir; (各ディレクトリに対してループ)
• mv -T "$dir" (ソースディレクトリを ...に行く) -Tは、シーズンフォルダが一意でない場合、エラー22を発生させます。つまり、同じディレクトリに「The Big Bang Theory Season」と「Season 22」はありません。)
•dirname「$dir」は、パスのあるディレクトリを返します。
• basename "$dir" はディレクトリ名を返します。
•sed "s /。シーズン([0-9])$/Season \1/i" は、対照的に大文字と小文字を区別しない正規表現を使用して魔法を実行します。

私の小さなテストでは動作します(mvの前に最初にechoを試してください)。

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

関連情報