
その中には多くのサブディレクトリがあり、そこには多くの拡張機能があるディレクトリがあります.no_sub
。
.no_sub
拡張子を持つすべてのファイルの名前を同じ名前に変更して.no_sub
削除したいと思います。
だからfoo.no_sub
- > foo
。
Bashでこれを行うことはできますか? (私はUbuntu 20.04を使用しています)
答え1
標準find
、sh
およびmv
:を使用してください。
find . -type f -name '*.no_sub' -exec sh -c '
for pathname do
mv -- "$pathname" "${pathname%.no_sub}"
done' sh {} +
.no_sub
名前が文字列で終わる現在のディレクトリ内または下の一般的なファイルを探します。これらのパス名のバッチに対して短いインラインシェルスクリプトが呼び出されます。このsh -c
スクリプトは、指定されたパス名の配置を繰り返し、ファイル名のサフィックスを削除してそれぞれの名前を変更します.no_sub
。ファイル名サフィックスの削除は、${variable%suffix}
標準パラメータ拡張を使用して行われます。
ファイル名の競合は解決されません。
これは似たような到着Marcus Müllerが提供するソリューション個々のファイルの名前の変更は、同じ方法で行われますが、find
隠された名前を選択し、通常のファイルに対してのみ繰り返す明示的なファイルタイプフィルタを含む方法でパス名のループリストを生成するために使用されます。
また見なさい:「find」の-execオプションについて
インラインスクリプトに与えられたすべてのファイル名は次に終わることを知っています.no_sub
。.no_sub
find . -type f -name '*.no_sub' -exec sh -c '
for pathname do
mv -- "$pathname" "${pathname%.*}"
done' sh {} +
答え2
シェルの機能を使用してすべてのファイルをインポートし、通常のツールを使用して名前を変更します。
shopt -s nullglob ## as recommended and explained in the comments
shopt -s globstar
shopt -s dotglob
for fname in **/*.no_sub ; do
mv -- "${fname}" "${fname%.no_sub}"
done
ここでは、
shopt -s globstar
**
再帰的なグローブとして有効shopt -s dotglob
発見できる.*.no_sub
- ループは
for
すべてのファイル(絶対に分析しls
ないでください) - 構文
mv
はmv source target
; - 時には過度に慎重なこともありますが、ただ変数名に混同があってはならないので、それより
${fname}
は良いという点も気に入っています。現在のファイルである$fname
変数の内容に展開されます。fname
- 変数の拡張は
${variable%pattern}
変数の内容に拡張されますが、サフィックス・パターンで縮小されます。pattern
答え3
以下を使用してfind
これを実行できますxargs
。
find . -name '*.nosub' -print0 | xargs -0 rename .nosub ""
オプションと-print0
オプションは、スペースを含むファイル名を正しく処理するために使用されます。このコマンドはソフトウェアパッケージで提供されます。find
-0
xargs
rename
util-linux
答え4
POSIXの使用find
:
find . -type f -name '*.no_sub' \
-exec perl -le '
rename $_, s/\.no_sub$//r
for @ARGV;
' {} +;
.no_sub
名前で終わる一般的なファイルを見つけますperl
。
その後、Perl は組み込みの名前変更コマンドを呼び出し、次の .no_sub 拡張子を削除して、本質的にファイルを移動します。