ファイル名の点を下線で置き換えます(拡張子を除く)。

ファイル名の点を下線で置き換えます(拡張子を除く)。

誰かがファイルの名前を変更する方法を提案できますか?

head.body.date.txt

到着する:

head_body_date.txt

名前変更を行う一行文はありますか?Unix

答え1

ファイル名を繰り返し、パラメータ拡張を使用して変換します。

for f in *.*.*.txt; do i="${f%.txt}"; echo mv -i -- "$f" "${i//./_}.txt"; done

パラメータ拡張モードでは、ファイル名の${f//./_}すべてのsを.s()に置き換えます。_$f

上記は実際の名前を変更するために練習を実行し、以下を削除しますecho

for f in *.*.*.txt; do i="${f%.txt}"; mv -i -- "$f" "${i//./_}.txt"; done

以下だけでなく、すべての拡張を処理したい場合.txt

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     echo mv -i -- "$f" "${pre//./_}.${suf}"; done

削除後の実際の動作確認echo

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     mv -i -- "$f" "${pre//./_}.${suf}"; done

通常、ポイント数に関係なく、少なくとも1つは次のようになります。

for f in *.*; do pre="${f%.*}"; suf="${f##*.}"; \
                 mv -i -- "$f" "${pre//./_}.${suf}"; done

答え2

perlベースとしてrename

$ rename -n 's/\.[^.]+$(*SKIP)(*F)|\./_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)
  • \.[^.]+$(*SKIP)(*F)このパターンをスキップして代替一致を見つけます。
  • |\./_/gすべて.次へ交換_

または否定的な予測を使用してください。

$ rename -n 's/\.(?![^.]+$)/_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)

確認したら、この-nオプションを削除してください。

答え3

rename 's/\.(?=[^.]*\.)/_/g' *.txt

.正規表現置換を使用して、ファイル名の最後のインスタンス(非キャプチャ予測)を除くすべてのエントリを見つけ、必要に応じてGeneralizeに置き換えます_*.*

(この特定のバージョンは経由renameでインストールされているようですutil-linux)。私はUbuntu 12.04(はい、真剣に古いマシン)を使用しています。

答え4

mv1行で使用sedし、次の操作を行います。rev

mv "head.body.date.txt" "$(echo head.body.date.txt | rev | sed 's/\./_/2g' | rev)"

txt現在、すべての表現のすべてのファイルに適用したい場合は、globを使用するのがうまくいくようですが、1行でループを実行mvできます。for

for file in *.txt; do mv "$file" "$(echo $file | rev | sed 's/\./_/2g' | rev)"; done

少し長いですが、ループ内の複数のパターンを一致させることができます!

関連情報