すべてのファイル名を正確に16文字(数字と小文字)に変更したいと思います。[0-9a-z]{16}
次のコードスニペットで[0-9a-z]\{16\}
プレースホルダを試しましたが、うまくregX
いきません。
for file in <regX>
do
mv "$file" "${file}.txt"
done
答え1
シェルワイルドカードモード正規表現ではありません。。似ているように見えるかもしれませんが、ある点では非常に異なる動作をします。
正規表現は、[0-9a-z]{16}
上記の文字範囲を含む16文字の文字列と一致します(埋め込まれた文字列は長くなる可能性があります)。
同等のシェルワイルドカードパターンは次のようになります。
*[0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z]*
このためです
- ワイルドカードモードは、「最初のN回の繰り返し」修飾子をサポートしません。
- デフォルトでは、ワイルドカードパターンは開始と終了に固定されています。だから
*
パターンの始めと終わりに挿入します。 A は*
任意の数のすべての文字と一致します。一致が必要な場合は、以下を削除してください。正確に16文字。
Perlを使用して16ビット文字列を作成できます[0-9a-z]
。
$ pattern="$( perl -e 'print "[0-9a-z]" x 16' )"
を使用すると、オプションでbash
現在のディレクトリのすべての名前を繰り返し、名前が正規表現と一致するかどうかをテストできます。
for name in *; do
if [[ -f "$name" ]] && [[ "$name" =~ ^[0-9a-z]{16}$ ]]; then
echo mv "$name" "$name.txt"
fi
done
echo
それが正しいことをしていることがわかったら、それを取り除きます。
長い名前が一致しないようにパターンを固定しました。また、-f
私たちが得た名前が実際に一般的なファイルの名前であることを確認するためにテストしました。
答え2
そして外部グローバル変数
shopt -s extglob
for file in +([0-9a-z])
do
[[ ${#file} == 16 ]] && echo mv "$file" "${file}.txt"
done
+([0-9a-z])
1 つ以上の[0-9a-z]
文字を表します。${#file}
ファイル名の長さを指定しますecho
テストの実行に使用し、すべてがうまくいったら削除します。
答え3
rename
Perl-rename(Debianベースのシステムまたは他のシステムから呼び出されます)がある場合は、perl-rename
次のことができます。
perl-rename -n 's/^[0-9a-z]{16}$/$&.txt/' *
要件を満たしている場合は、それらを削除して-n
実際にファイル名を変更してください。構文perl-rename
はperlコマンドです。ここでは、代替演算子(s/from/to/
)を使用してfrom
を置き換えますto
。この場合、from
正規表現は「一致する項目」を表すto
特殊変数$&
と拡張子です.txt
。
Shell globを使用してこれを行うには(使用@クサラナンダまたは@サンディップメソッドは完了のためです):
for f in [0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z][0-9a-z]; do
mv -- "$f" "$f".txt
done
GNUの使用find
:
find . -regextype posix-extended -regex '.*/[0-9a-z]{16}' -exec mv {} {}".txt" \;
答え4
L16=$(csh -c 'repeat 16 echo -n "?"')
find . -name "$L16" ! -name '*[!0-9a-z]*' -exec sh -c '
mv "$1" "$1.txt"
' {} {} \;