我有一个包含数千个文件的音频样本库。我想打乱/随机化这些文件的顺序。有人可以给我一个 bash 脚本/行,该脚本/行会在文件夹中的所有文件(包括子文件夹中的文件)前面附加一个随机字符。不过,我不想在任何文件夹名称前面附加一个随机字符。
<小时 />示例:
底鼓73.wav
底鼓 SUB.wav
Kick808.mp3
重命名为:
f_Kickdrum73.wav
!_Kickdrum SUB.wav
4_Kick808.mp3
如果可能,我希望能够多次运行此脚本,但在后续运行中,它只是更改随机预置的字符,而不是预置新字符。
我的一些尝试:
find ~/Desktop/test -type f -print0 | xargs -0 -n1 bash -c 'mv "$0" "a${0}"'
find ~/Desktop/test/ -type f -exec mv -v {} $(cat a {}) ;
find ~/Desktop/test/ -type f -exec echo -e "Zn$(cat !)" > !Hat 15.wav
for file in *; do
mv -v "$file" $RANDOM_"$file"
done
注意:我运行的是 macOS。
使用Fixit先生的代码的最新尝试:
find . -type f -maxdepth 999 -not -name ".*" |
cut -c 3- - |
while read F; do
randomCharacter="${F:2:1}"
if [ $randomCharacter == '_' ]; then
new="${F:1}"
else
new="_$F"
fi
fileName="`basename $new`"
newFilename="`jot -r -c $fileName 1 A Z`"
filePath="`dirname $new`"
newFilePath="$filePath$newFilename"
mv -v "$F" "$newFilePath"
done
这是我的第一个答案,增强为做子目录。
将以下内容放在文件randomize
if [[ $# != 1 || ! -d "$1" ]]; then
echo "usage: $0 <path>"
else
find $1 -type f -not -name ".*" |
while read F; do
FDIR=`dirname "$F"`
FNAME=`basename "$F"`
char2="${FNAME:1:1}"
if [ $char2 == '_' ]; then
new="${FNAME:1}"
else
new="_$FNAME"
fi
new=`jot -r -w "%c$new" 1 A Z`
echo mv "$F" "${FDIR}/${new}"
done
fi
使用chmod a+x randomize
设置权限。
然后用randomize your/path
调用它。
它将回显重命名所有内容所需的命令,因此您可以检查它们以确保它们对您有用。如果它们看起来正确,则可以从第 3 行到最后一行中删除echo
并重新运行脚本。
cd ~/Desktop/test
,则
find . -type f -maxdepth 1 -not -name ".*" |
cut -c 3- - |
while read F; do
char2="${F:2:1}"
if [ $char2 == '_' ]; then
new="${F:1}"
else
new="_$F"
fi
new=`jot -r -w "%c$new" 1 A Z`
mv "$F" "$new"
done
find . -type f -maxdepth 1 -not -name ".*"
将获取当前目录中的所有文件,但不会获取隐藏文件(以"."开头的名称)
cut -c 3- -
将从名称中删除前 2 个字符。find
输出路径,./
会妨碍处理前缀。
while read VAR; do <stuff>; done
是一种一次处理一行的方法
char2="${VAR:2:1}
将变量char2
设置为变量VAR
的第 2 个字符。
if - then - else
将new
设置为文件名,前面有_
,或者去掉前面的随机字符。
jot -r -w "%c$new" 1 A Z
从 A-Z 随机添加 1 个字符到new
的开头
mv old new
重命名文件
您也可以在 bash 中完成所有操作,并且有几种方法可以解决它。第一种是简单地创建一个包含要用作前缀的任何字母的letters
数组,然后生成一个随机数来用于选择数组的元素,例如
#!/bin/bash
letters=({0..9} {A..Z} {a..z}) ## array with [0-9] [A-Z] [a-z]
for i in *; do
num=$(($RANDOM % 63)) ## generate number
## remove echo to actually move file
echo "mv "$i" "${letters[num]}_$i"" ## move file
done
示例使用/输出
当前脚本输出它将进行的更改,您必须删除mv
命令周围的echo "..."
并修复转义引号以实际应用更改:
$ bash ../randprefix.sh
mv "Kick808.mp3" "4_Kick808.mp3"
mv "Kickdrum SUB.wav" "h_Kickdrum SUB.wav"
mv "Kickdrum73.wav" "l_Kickdrum73.wav"
您也可以通过生成一个随机数来表示48
(字符'0'
)到126
(字符'~'
)之间的 ASCII 字符,不包括 'backtick
'),然后将随机数转换为 ASCII 字符并用它作为文件名前缀,例如
#!/bin/bash
for i in *; do
num=$((($RANDOM % 78) + 48)) ## generate number for '0' - '~'
letter=$(printf "\$(printf '%03o' "$num")") ## letter from number
while [ "$letter" = '`' ]; do ## exclude '`'
num=$((($RANDOM % 78) + 48)) ## generate number
letter=$(printf "\$(printf '%03o' "$num")")
done
## remove echo to actually move file
echo "mv "$i" "${letter}_$i"" ## move file
done
(类似的输出,除backtick
以外的所有标点符号都是可能的)
在每种情况下,您都需要将脚本放在您的路径中或从您要在其中移动文件的目录中调用它(您将拆分dirname
和basename
并将它们重新连接在一起以使脚本可调用,将目录作为参数进行搜索 - 这留给您)