问题是我无法弄清楚如何仅计算移动文件的“成功”尝试。
我的脚本将$ PATH中的目录作为目标,并尝试从指定目录中获取文件(直到该目录为空),以随机顺序将其随机排列,然后从$ PATH移至目录。
x=0
while [[ $(ls -A Directory/jpg | wc -l) -gt 0 ]]
do
for i in "${destination[@]}"
do
shuf -zn1 -e Directory/jpg/*.jpg | xargs -0 mv -vt $i/somedir 2>/dev/null
x=$((x + 1))
done
done
我的“ x”计数器实际上大于“目录/ jpg”中的文件数量,我想“ x”仅表示复制的文件的确切数量。
答案 0 :(得分:0)
我对脚本进行了一些修改以进行测试:
#!/bin/bash
destination[0]=dest1
destination[1]=dest2
destination[2]=dest3
x=0
while [[ $(ls -A source | wc -l) -gt 0 ]]
do
for i in "${destination[@]}"
do
shuf -zn1 -e source/* | xargs -0 mv -vt $i
x=$((x + 1))
done
done
echo $x
因此,在source
中有三个目标目录和不同数量的文件时,我注意到x
始终是destination
数组中元素数量的倍数。
删除2>/dev/null
发现了一个隐藏的问题:
... # other mv output
renamed 'source/file14' -> 'dest2/file14'
renamed 'source/file16' -> 'dest3/file16'
renamed 'source/file5' -> 'dest1/file5'
mv: cannot stat 'source/*': No such file or directory
mv: cannot stat 'source/*': No such file or directory
计算了最后两个失败的动作!
for i in "${destination[@]}"
总是要循环播放等于destination
数组中元素数量的次数。也就是说,如果destination
具有三个元素,即使文件数量不多,循环也将始终使用i = 1
,i = 2
和i = 3
执行。 for循环将始终将x
中的元素数量增加destination
。因此,x
将大于移动的文件数。 (除非文件数是目标数组中元素数的倍数)
可以通过在for循环内部添加测试以检查是否存在更多要移动的文件来解决此问题:
#!/bin/bash
destination[0]=dest1
destination[1]=dest2
destination[2]=dest3
x=0
while [[ $(ls -A source | wc -l) -gt 0 ]]
do
for i in "${destination[@]}"
do
shuf -zn1 -e source/* | xargs -0 mv -vt $i
x=$((x + 1))
[[ $(ls -A source | wc -l) -eq 0 ]] && break # exit the loop if there are no more files to move
done
done
答案 1 :(得分:0)
请考虑使用&&检查mv命令的结果并有条件地执行增量操作。
这是bash惯用语:
command && other-command-if-command-was successful
在上面的示例中,仅当命令返回零退出状态时,other-command才会执行。这是我对您的程序的修改:
x=0
while [[ $(ls -A Directory/jpg | wc -l) -gt 0 ]]
do
for i in "${destination[@]}"
do
shuf -zn1 -e Directory/jpg/*.jpg | xargs -0 mv -vt $i/somedir 2>/dev/null && x=$((x + 1))
done
done
上面的代码可能错误地假定xargs将返回mv的退出状态。我认为不会。相反,在这种情况下最好避免使用xargs。毕竟,shuf只返回一个条目。这是对代码的较大修改,效果更好:
x=0
while [[ $(ls -A Directory/jpg | wc -l) -gt 0 ]]
do
for i in "${destination[@]}"
do
random_file=$(shuf -zn1 -e Directory/jpg/*.jpg)
mv "$random_file" "$i/somedir" && x=$((x + 1))
done
done