Bash 脚本,用于在文件夹中的所有文件前面附加单个随机字符



我有一个包含数千个文件的音频样本库。我想打乱/随机化这些文件的顺序。有人可以给我一个 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 - elsenew设置为文件名,前面有_,或者去掉前面的随机字符。

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以外的所有标点符号都是可能的)

在每种情况下,您都需要将脚本放在您的路径中或从您要在其中移动文件的目录中调用它(您将拆分dirnamebasename并将它们重新连接在一起以使脚本可调用,将目录作为参数进行搜索 - 这留给您)

相关内容

  • 没有找到相关文章