このコマンドを使用してファイルの名前を変更します。
for fname in *;
do
mv "$fname" $(echo "$fname" | sha1sum | cut -f1 -d' ')
done
ただし、現在のディレクトリでのみ名前が変更されます。多くのディレクトリがあり、各ディレクトリには異なるディレクトリが含まれ、最後のディレクトリツリーにはファイルが含まれているとします。任意の文字で名前を変更したいです。
私はそれがうまくいくべきだfind . -type f
と思って試してみましたが、それでも操作コマンドを取得できませんでした。
答え1
そして、次を見つけてください。
find . -type f -exec sh -c 'SHELL COMMAND' {} \;
これはSHELL COMMAND
見つかった各ファイルを順番に呼び出します。"$0"
したがって、ファイル名はです。
find . -type f -exec sh -c '
mv "$0" "${0%/*}/$(printf "%s\n" "${0##*/}" | sha1sum | cut -d" " -f1)"
' {} \;
(ファイル名がある場合、または問題を引き起こす可能性がある他の状況がある場合は、printf
代わりに使用してください。)echo
-e
-n
echo
シェルを一括で呼び出すと、作業を高速化できます。
find . -type f -exec sh -c 'for x; do
mv "$x" "${x%/*}/$(printf "%s\n" "${x##*/}" | sha1sum | cut -d" " -f1)";
done' _ {} +
zshには、現在のディレクトリとサブディレクトリのすべてのファイルを再帰的に一致させる簡単な方法があります。これ.
グローバル予選通常のファイルに一致を制限し、D
ドットファイルを含めます。
for x in **/*(.D); do mv …; done
Bash ≥ 4では、再帰的に実行し、shopt -s globstar
現在**/*
のディレクトリとサブディレクトリのすべてのファイルを一致させるために使用できます。ループ内で通常のファイルをフィルタリングする必要があります。
shopt -s globstar; GLOBIGNORE=".:.."
for x in **/*; do if [[ -f $x ]]; then mv …; done
答え2
ヘルパースクリプト/tmp/tmp.shを作成します。
#!/bin/bash
mv "$1" $(echo "$1" | sha1sum | cut -f1 -d' ')
実行可能にしてから呼び出します。
find . -type f -execdir /tmp/tmp.sh {} ";"
答え3
Bash 4+を使用している場合は、次のことができます。
#!/bin/bash
shopt -s globstar
for fname in **/*; do
if [ -f "$fname" ]; then
mv ...
fi
done
Bash Hacker Wikiから:
新しいシェルオプションglobstarがあります。有効にすると、Bashは**で再帰的なワイルドカードを実行します。つまり、現在のレベルだけでなく、ファイルシステムの現在の場所にあるすべてのディレクトリとファイルと一致します。
答え4
これはすべてのスペースを処理します...
set -f; IFS=
while read -r -d $'\0' fname ;do
mv ...
done < <(find . -type f -name '*' -print0)
set +f; IFS=$' \t\n' # you don't have to reset unless it effects subsequent code