web-dev-qa-db-ja.com

ファイル名のドットを拡張子以外のアンダースコアに置き換える

誰かがファイル名を変更する方法について提案できますか:

head.body.date.txt

に:

head_body_date.txt

nixで名前変更を行う1行のステートメントはありますか?

9
S G

ファイル名を反復処理し、変換にパラメーター展開を使用します。

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
9
heemayl

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_オプションを削除します

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

正規表現の置換を使用して、ファイル名内の.の最後のインスタンスを除くすべてを検索し(先読みなし)、それらを_に置き換えます。必要に応じて、*.*にジェネラライズします。

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

3

bash

old=head.body.date.txt oldb=${old%.*} olde=${old##*.} ; \
mv -- "$old" "${oldb//./_}.${olde}"
2
agc

mvsedrevを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

少し長くなりますが、ループ内のいくつかのパターンに一致させることができます。

1
Valentin B.