web-dev-qa-db-ja.com

Linuxで正規表現を使用してファイルの名前を変更する

次のような名前のファイルセットがあります。

Friends - 6x03 - Tow Ross' Denial.srt
Friends - 6x20 - Tow Mac and C.H.E.E.S.E..srt
Friends - 6x05 - Tow Joey's Porshe.srt

次のように名前を変更したい

S06E03.srt
S06E20.srt
S06E05.srt

linuxターミナルでジョブを実行するにはどうすればよいですか? renameをインストールしましたが、次を使用してエラーが発生します。

rename -n 's/(\w+) - (\d{1})x(\d{2})*$/S0$2E$3\.srt/' *.srt
39
orezvani

アスタリスクの前のドットを忘れました:

rename -n 's/(\w+) - (\d{1})x(\d{2}).*$/S0$2E$3\.srt/' *.srt

OpenSUSE、RedHat、Gentooでは、renameのPerlバージョンを使用する必要があります。 この回答 は、取得方法を示しています。 Archでは、パッケージの名前はPerl-rename

56
Thor

本当にクールなリルディディ。検索+ Perl + xargs + mv

xargs -n2を使用すると、1行に2つの引数を出力できます。 Perlのprint $_(最初に$ STDINを出力するため)と組み合わせると、強力な名前変更ツールになります。

find . -type f | Perl -pe 'print $_; s/input/output/' | xargs -n2 mv

Perl -pe 'print $_; s/OldName/NewName/' | xargs -n2の結果は次のようになります。

OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext

私のシステムでは、Perlのrenameをすぐに利用できませんでした。


どのように機能しますか?

  1. find . -type fはファイルパス(またはファイル名...ここで正規表現によって処理されるものを制御します!)を出力します。
  2. -pは正規表現によって処理されたファイルパスを出力し、-eはインラインスクリプトを実行します
  3. print $_は最初に元のファイル名を出力します(-pとは無関係)
  4. -n2は1行に2つの要素を出力します
  5. mvは前の行の入力を取得します
8
Jonathan Komar

Edit:IFSlsは、shに準拠したままです。

そのためにシェルスクリプトを実行します。

#!/bin/sh
for file in *.srt; do
  if [ -e "$file" ]; then
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
    mv "$file" "$newname"
  fi
done

前のスクリプト:

#!/bin/sh
IFS='
'
for file in `ls -1 *.srt`; do
  newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
  mv "$file" "$newname"
done
8
Creak

すべてのディストリビューションが、上記の例で使用されている正規表現をサポートするrenameユーティリティ(RedHat、Gentoo、およびそれらの派生物など)を出荷しているわけではありません。

使用しようとする代替手段はPerl-renameおよびmmv

7
gerrit_hoekstra

mmv (mass-move?)を使用します

シンプルですが便利です。任意の文字列に*を使用し、一致文字列の任意の文字に?を使用し、置換文字列に#Xを使用してX番目の一致を参照します。

あなたの場合:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt'

ここで、#1#2は、??(#1と#2に一致)によってキャプチャされる2桁を表します。
したがって、次の置換が行われます。

Friends - 6x?? - Tow *           .srt    matches
Friends - 6x03 - Tow Ross' Denial.srt    which is replaced by
            ↓↓
        S06E03.srt

mmvは、[および]および;によるマッチングも提供します。

renameだけでなく、move、copy、appendおよびlinkファイル。

詳細については、上記のリンクのmanページをご覧ください!

個人的には、番号をパディングするために使用し、辞書式にソートされたときに番号付きファイルが希望の順序で表示されるようにします:file_?.extfile_0#1.ext

5
xoxox

linuxがrenameを提供しない場合は、次も使用できます。

find . -type f -name "Friends*" -execdir bash -c 'mv "$1" "${1/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt}"' _ {} \;

私はこのスニペットを頻繁に使用して、コンソールで正規表現で置換を実行します。

私はシェルのものはあまり得意ではありませんが、このコードを理解している限り、その説明は次のようになります:findの検索結果はbashに渡されます-command(bash -c)ここで、検索結果はソースファイルとして$ 1内にあります。後続のターゲットは、サブシェル内の置換の結果です。ここで、$ 1のコンテンツ(ここでは、ちょうど1パラメーター置換{1 // find/replace})も検索結果になります。 {}-execdirのコンテンツに渡します

より良い説明をたくさんいただければ幸いです:)

注:正規表現のみをコピーアンドペーストしました。最初にサンプルファイルでテストしてください。システムによっては、\ dと\ wを[[:digit:]]や[[:alpha:]]などの文字クラスに変更する必要がある場合があります。ただし、グループでは\ 1が機能するはずです。

1
meistermuh

rnm を使用できます。

rnm -rs '/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt/' *.srt

説明:

  1. -rs/search_regex/replace_part/modifier形式の文字列を置き換えます
  2. (\d)(\d+)(\d)x(\d+)は、2つのキャプチャされたグループです(それぞれ\1\2)。

その他の例 こちら

0
Jahid