Я знаю, что есть гораздо более элегантные способы решения этой проблемы. Это предложение не будет работать для имен файлов, содержащих символы новой строки или имена, начинающиеся с точки, но должно быть достаточно надежным в противном случае:
# Create a temporary directory for rename targets (allows for a->b but b->a)
DIR='.tmp'
mkdir -p "$DIR"
# How many files
LS=($(ls))
NLS=$((${#LS}+1))
# Rename the files pseudo-randomly
for SRC in "${LS[@]}"
do
while :
do
# A poor approximation to a random selection. If you have `shuf`
# this could be considerably simplified.
RND=$((RANDOM % NLS))
DST="${LS[$RND]}"
echo "(trying RND=$RND -> DST=$DST)" >&2
# Keep retrying until we find an unused filename
test -n "$DST" && break
done
echo "$SRC -> $DST" >&2
mv -f "$SRC" "$DIR/$DST"
unset LS[$RND]
done
# Restore the renamed files to the now-empty directory
mv "$DIR"/* .
rmdir "$DIR"
Если вам нужно обрабатывать имена файлов, начинающиеся с точки, переместите временный каталог $ DIR
в другое место и измените команду ls
, добавив в нее флаг -A
. Если вам нужно обрабатывать имена файлов, содержащие символы новой строки, я бы порекомендовал вам использовать другой язык, например Perl или Python.