Переименование нескольких файлов в случайную строку переименовывает только один файл

57
4

Попытка переименовать файлы в случайную строку. Я взял код из ответа на этот вопрос, чтобы создать случайную строку символов.

#!/bin/bash

chars=( {a..z} {A..Z} {0..9} )

function rand_string {
local c=$1 ret=
while((c--)); do
ret+=${chars[$((RANDOM%${#chars[@]}))]}
done
printf '%s\n' "$ret"
}

output=$(rand_string 10)

Для практики я создал каталог в $HOME/practice с несколькими текстовыми файлами.

/Users/me/practice/testfile1.txt
/Users/me/practice/testfile2.txt
/Users/me/practice/testfile3.txt

При попытке переименовать эти файлы в случайную строку, вместо того, чтобы получать 3 случайных имени, вместо этого я оставляю 1 файл, переименованный в случайную строку.

for file in $HOME/practice/*
do
mv "$file" $HOME/practice/"$output"
done

#result
/Users/me/practice/i6TP3wiMDD

Замена mv "$file" ~/practice/"$output" с помощью echo "$file" "$output" показывает мне, что случайная строка повторяется после каждого файла вместо генерации новой случайной строки для каждого файла.

/Users/me/practice/testfile1.txt i6TP3wiMDD
/Users/me/practice/testfile2.txt i6TP3wiMDD
/Users/me/practice/testfile3.txt i6TP3wiMDD

Мой вопрос состоит из двух частей:

Почему только 1 файл переименован? Как я могу создать новую случайную строку для каждого переименованного файла?

Я также скажу, что вышеупомянутый сценарий случайных символов выше моего текущего понимания. Я знаю, что он работает для генерации случайных символов. Но внутренняя работа его все еще несколько неясна для меня.

спросил(а) 2016-10-05T08:09:00+03:00 3 года, 11 месяцев назад
1
Решение
57

Проблема в том, что вы генерируете только экземпляр случайного значения и сохраняете его в output переменной и используете то же самое, чтобы переименовать все файлы в цикле. См. Расширение сценария оболочки, которое появляется при запуске с set -x после определения she-bang (#!/bin/bash).

+++ rand_string 10
+++ local c=10 ret=
+++ (( c-- ))
+++ ret+=O
+++ (( c-- ))
+++ ret+=k
+++ (( c-- ))
+++ ret+=H
+++ (( c-- ))
+++ ret+=Q
+++ (( c-- ))
+++ ret+=1
+++ (( c-- ))
+++ ret+=u
+++ (( c-- ))
+++ ret+=9
+++ (( c-- ))
+++ ret+=4
+++ (( c-- ))
+++ ret+=c
+++ (( c-- ))
+++ ret+=C
+++ (( c-- ))
+++ printf '%s\n' OkHQ1u94cC # <--- See the same random file-names used throughout the files
++ output=OkHQ1u94cC
++ for file in '*.txt'
++ mv 1.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv 2.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv 5000.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv 5100.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv abc.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv file.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv final.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv ini1.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv ini2.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv listing.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv names.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv parameters.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv properties.txt OkHQ1u94cC
++ for file in '*.txt'
++ mv result.txt OkHQ1u94cC

Вышеприведенные данные содержат мои данные. Лучший способ - исправить цикл for в функции rename, вызывая функцию во время расширения. Как ниже

#!/bin/bash

for file in $HOME/practice/*
do
mv "$file" $HOME/practice/"$(rand_string 10)" # <-- Here the random string length can be controlled as you need.
done

Теперь с приведенным выше исправлением вы можете увидеть мой сценарий фактического переименования моих .csv файлов, расширенных как

+++ rand_string 10
+++ local c=10 ret=
+++ (( c-- ))
+++ ret+=7
+++ (( c-- ))
+++ ret+=j
+++ (( c-- ))
+++ ret+=U
+++ (( c-- ))
+++ ret+=K
+++ (( c-- ))
+++ ret+=l
+++ (( c-- ))
+++ ret+=V
+++ (( c-- ))
+++ ret+=l
+++ (( c-- ))
+++ ret+=6
+++ (( c-- ))
+++ ret+=8
+++ (( c-- ))
+++ ret+=8
+++ (( c-- ))
+++ printf '%s\n' 7jUKlVl688
++ output=7jUKlVl688
++ for file in '*.csv'
+++ rand_string 10
+++ local c=10 ret=
+++ (( c-- ))
+++ ret+=N
+++ (( c-- ))
+++ ret+=B
+++ (( c-- ))
+++ ret+=O
+++ (( c-- ))
+++ ret+=p
+++ (( c-- ))
+++ ret+=j
+++ (( c-- ))
+++ ret+=5
+++ (( c-- ))
+++ ret+=T
+++ (( c-- ))
+++ ret+=b
+++ (( c-- ))
+++ ret+=S
+++ (( c-- ))
+++ ret+=R
+++ (( c-- ))
+++ printf '%s\n' NBOpj5TbSR
++ mv 1.csv NBOpj5TbSR # <- Unique file names generated.
+++ rand_string 10
+++ local c=10 ret=
+++ (( c-- ))
+++ ret+=N
+++ (( c-- ))
+++ ret+=R
+++ (( c-- ))
+++ ret+=Y
+++ (( c-- ))
+++ ret+=C
+++ (( c-- ))
+++ ret+=C
+++ (( c-- ))
+++ ret+=X
+++ (( c-- ))
+++ ret+=L
+++ (( c-- ))
+++ ret+=0
+++ (( c-- ))
+++ ret+=e
+++ (( c-- ))
+++ ret+=l
+++ (( c-- ))
+++ printf '%s\n' NRYCCXL0el
++ mv 2.csv NRYCCXL0el # <- Unique file names generated.

ответил(а) 2016-10-05T08:21:00+03:00 3 года, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема