如何交换文件夹中大量文件的名称?

如何交换文件夹中大量文件的名称?

我想要随机化文件夹中大约 350 个文件的名称,但我想要拥有这些文件最初的所有名称。我的意思是我想要文件夹中的所有名称都是从原始名称中随机生成的,没有新名称,也没有名称丢失。这可能吗?

(如果我没有清楚地说出我的问题,请随时编辑这个问题)

答案1

mkdir aux
ls | shuf > a                                # a=randomize list of files
(tail -n +2 a ; head -1 a) > b               # b=rotate a one line
paste a b > c                                # c=(name1 name2)*
gawk '{system( "mv " $1 " aux/" $2)}' c      # mv name1 -> aux/name2
mv aux/* .                                   # mv aux/name -> name
rm a b                                     

如有必要,请继续c恢复。 (为辅助文件选择一个更好的名称)

答案2

└-(>:) for i in `seq -w 1 10`; do echo $i > nonce-$i; done 
└-(>:) ls
nonce-01  nonce-02  nonce-03  nonce-04  nonce-05  nonce-06  nonce-07  nonce-08  nonce-09  nonce-10
└-(>:) for i in nonce*; do echo $i; cat $i; done
nonce-01
01
nonce-02
02
nonce-03
03
nonce-04
04
nonce-05
05
nonce-06
06
nonce-07
07
nonce-08
08
nonce-09
09
nonce-10
10
└-(>:) ../shuffle test
└-(>:) for i in nonce*; do echo $i; cat $i; done
nonce-01
06
nonce-02
03
nonce-03
04
nonce-04
02
nonce-05
09
nonce-06
10
nonce-07
05
nonce-08
08
nonce-09
07
nonce-10
01

这是代码:

#!/bin/bash
[ -z $1 ] && echo 'please submit a target directory' && exit 1 
TargetDir=${1}
cd $TargetDir
Sourcearray=( * )
function checkArray
{
 for item in ${dest[@]}
  do
   [[ "$item" == "$1" ]] && return 0 # Exists in dest
 done
 return 1 # Not found
}
#let's shuffle the array randomly 

while [ "${#dest[@]}" -ne "${#Sourcearray[@]}" ]
do
     rand=$[ $RANDOM % ${#Sourcearray[@]} ] 
      checkArray "${Sourcearray[$rand]}" || dest=(${dest[@]} "${Sourcearray[$rand]}")
done

let i=0 
#let mv the source file to dest file name 
while [[ "${i}" -ne "${#dest[@]}" ]] ; do 
    mv ${Sourcearray[$i]} tmp-${dest[$i]}
    let i=$i+1
done  
# and rename to go back to the original name 
rename 's/tmp-//' *

答案3

这是一个想法:

  • 获取原始名称列表。保存。
  • 保存列表的打乱版本 ( sort -R)。
  • 以非冲突的方式破坏原始列表,例如,通过向每个名称附加一些内容。
  • 移动原始文件,以便它们反映损坏的列表(按顺序)。
  • 移动损坏的文件,使其反映打乱后的原始列表。

在基本的 shell 代码中,假设文件名中没有换行符,当前目录是混洗的目标目录,并且外部目录可写:

  find . -type f > ../list 
  < list sort -R > ../shuffled
  while read f; do mv "$f" "$f".tmp; done < ../list
  exec 3<../shuffled
  while read f; do read s <&3; mv "$f".tmp "$s"; done < ../list
  exec 3>&-  

答案4

没有众所周知的命令可以做到这一点,但幸运的是 shell 解释器可以非常轻松地完成此任务以及类似的任务。例如:

for i in /my/this/dir/*;do mv -vf "$i" "$i.$RANDOM";done

将逐步遍历/my/this/dir目录中的文件,并为此执行mv(重命名)命令,该命令会在其名称后附加 0 到 32767 之间的随机数。例如,如果您对目录执行此命令/sbin,它将重命名此处的文件,以便:

ifconfig -> ifconfig.4553
ip -> ip.12767
...

不要在 /sbin 中执行此操作,它会杀死您的系统!(但这会很有趣:-))

但要注意,如果这不是你想要的,那么恢复它可能会更困难(另一条单线,呵呵)。因此,在运行此脚本之前,您可以通过添加mv前缀来测试它echo

for i in /my/this/dir/*;do echo mv -vf "$i" "$i.$RANDOM";done

第二个单行脚本不会执行任何操作,只会打印在mv没有echo.

相关内容