誰かがファイル名を変更する方法について提案できますか:
head.body.date.txt
に:
head_body_date.txt
nixで名前変更を行う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
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
_オプションを削除します
rename 's/\.(?=[^.]*\.)/_/g' *.txt
正規表現の置換を使用して、ファイル名内の.
の最後のインスタンスを除くすべてを検索し(先読みなし)、それらを_
に置き換えます。必要に応じて、*.*
にジェネラライズします。
(この特定のバージョンのrename
はutil-linux
経由でインストールされているようです)。私はUbuntu 12.04
を使用しています(そうです、かなり古いマシンです)。
bash
:
old=head.body.date.txt oldb=${old%.*} olde=${old##*.} ; \
mv -- "$old" "${oldb//./_}.${olde}"
mv
、sed
、rev
を1行で使用:
mv "head.body.date.txt" "$(echo head.body.date.txt | rev | sed 's/\./_/2g' | rev)"
現在の担当者のすべてのtxt
ファイルにそれを適用する場合、mv
の仕組みが原因でグロブを使用するのは難しいようですが、for
ループを1回で実行できますライナー:
for file in *.txt; do mv "$file" "$(echo $file | rev | sed 's/\./_/2g' | rev)"; done
少し長くなりますが、ループ内のいくつかのパターンに一致させることができます。