Linuxでファイル名の一部を変更するには?

Linuxでファイル名の一部を変更するには?

可変長ファイル名「abcdef - ghijkl.pdf」を取得し、「ghijkl - abcdef.pdf」に名前を変更します。

単一フォルダ内のすべてのファイルのコマンドラインスクリプトでこれをどのように達成できますか?

答え1

Ubuntuを使用しているので、少なくともPerlベースrenameまたはprename

$ rename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
rename(abcdef - ghijkl.pdf, ghijkl - abcdef.pdf)

$ prename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
abcdef - ghijkl.pdf renamed as ghijkl - abcdef.pdf

またはインストールして使用することができます。mmv

$ mmv -n '* - *.pdf' '#2 - #1.pdf'
abcdef - ghijkl.pdf -> ghijkl - abcdef.pdf

(すべての場合、削除は-n実際に作業を完了することです。)

答え2

バッシュ使用:

[[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
  mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"

これはbashの正規表現テスト演算子を使用して、指定された=~ファイル名(in)がパターンと一致することを確認します$f。 「ダッシュ以外のすべて、スペースダッシュスペース、ピリオドを除くすべて、ピリオド、その後のすべて」。ファイル名がパターンと一致する場合、正規表現の括弧で囲まれた子部分の一致ビットが BASH_REMATCH 配列の要素に割り当てられます。

特定のフォルダ内のすべてのファイルに対してこれを行うには:

cd /to/that/folder
for f in *
do
  [ -f "$f" ] || continue
  [[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] && 
    mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
done

のみ使用POSIX 指定変数の拡張:

pre=${f%%.*}
ext=${f##*.}
mv "$f" "${pre##*- } - ${pre%% -*}.$ext"

答え3

次のコマンドを使用してスクリプトを作成できます。

\ls *-*.pdf | sed 's/\(.*\)-\(.*\).pdf/mv \1-\2.pdf \2-\1.pdf/' > script_mv.bash

その後、スクリプトが正しいことを確認して実行できます。

. ./script_mv.bash

私はlsのオプションを取り消すので、\lsを書きました。

sed モードの意味は次のとおりです。

  • 1、「-」、2、「.pdf」のいずれかが見つかりました。
  • 両方の内容を()で囲み、\ 1と\ 2という名前を取得します。
  • その後、mv行をコピーし、\ 1と\ 2のためにファイル名を再作成できます。

答え4

"xxx-yyyy.ddd" 名前パターンに関連する恥ずかしい答えです。

find -type f | while read flnm ; do basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}'; done

ファイルを見つけ、while readループに名前を付けます。そこからbasenameを使用して名前を抽出し、Awkに提供します。 awk は複数のフィールド区切り文字、スペース、ピリオドを使用し、必要な順序でフィールドを再印刷します。

abcdef - ghijkl.pdf

~になる

ghijkl - abcdef.pdf

実際の適用...ファイル名をこの新しいスキーマ名に変更します。

find -type f | while read flnm ; do mv "$(basename "$flnm")"  "$(basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}')"; done

唯一の違いは、mvコマンドを含み、名前を文字列で囲むことです。

関連情報