次の形式のファイルフォルダを含むフォルダがあります。
resultstatsDF_iris_2017-05-26--21-33-35-437096_methodnr-2_percentage-0.05_seed-0.wcr
私はこれらのそれぞれの日付と時刻を削除したいので、この場合は次のような結果を得ます。
resultstatsDF_iris_methodnr-2_percentage-0.05_seed-0.wcr
Bashでこれを行うにはどうすればよいですか?
答え1
本当にやりたいなら「バッシュと一緒に」、その後
find . -name '*.wcr' -execdir bash -c '
shopt -s extglob; for f; do echo mv -- "$f" "${f/_+([0-9-])_/_}"; done
' bash {} +
+([0-9-])
これは、セットで発生する1つ以上の文字に一致する拡張globに依存します。[0-9-]
${f/_2017+([0-9-])_/_}
たとえば、単純に数字とダッシュを一致させるのが一般的である場合は、置換をより具体的にすることができます。
注:削除 echo
あなたが望むことをしていることを確信してください。
答え2
find
+使用prename
(Perlの名前変更)コマンド:
find yourfolder -type f -name "*.wcr" -exec prename 's/^(.+)_[0-9]{4}-[0-9]{2}-[0-9]{2}[^_]+(_.*)$/$1$2/' {} +
prename
アクションを取らずに結果を表示するには、-n
オプション(名前を変更せずに名前を変更するファイル名を印刷します。):
man rename
[0-9]{4}-[0-9]{2}-[0-9]{2}
- パターンポインティング日付- 類似部分文字列(例2017-05-26
:)
答え3
使用パールの名前を変更するコマンド(すべてのバリアント、単にutil-linuxを除くrename
):
find . -type f -name \*.wcr -exec rename 's/_\d{4}-(\d{2}-){2}-(\d{2}-){3}\d+_/_/' {} +
答え4
ファイルが常に1つのディレクトリ深さの場合は、次のモードを使用できますfor x in */*_20*_*
。使用するモードは、名前を変更したくない他のファイルがある可能性によって異なります。今提示したパターンは、日付が次に始まり、名前20
に含まれているすべてのファイル_20
とそれ以降の元に戻す項目の名前を変更する必要があると仮定します。
名前を変更するにはシェルループを使用できますパラメータ拡張新しいファイル名を構築するための設定です。
for old_name in ./*/*_20_*_*; do
base=${old_name##*/} # remove the directory part
prefix=${base%%_20*} # remove everything from _20
suffix=${base#*_20} # remove everything up to _20
suffix=${suffix#*_} # ... then everything before the first remaining _
mv "$old_name" "${old_name%/*}/${prefix}_${suffix}"
done
ファイルの深さが異なる場合は、bash≥4.3でshopt -s globstar
thenを実行できますfor x in **/*_20*_*; …
。これ模様**
globstar
オンの場合、すべてのディレクトリの深さと一致します。これはbash 4.0〜4.2でも機能しますが、ディレクトリのシンボリックリンクも通過することに注意してください。これは警告なしでzshとkshでも動作し、zshでもすぐに動作し、set -o globstar
kshでも動作します。