如何使用find和xargs(GNU Bash)将拼合的文件复制到一个目录中

| 我需要查找所有文件(例如,扩展名为ABC)并将其复制到一个目录中,但要创建唯一的文件名,而不要覆盖任何可能具有相同名称的文件。 像这样:
find /tmp -name \\*.ABC | xargs cp \'{}\' somedir/$(echo {} | md5sum | cut -c1-6){} \\;
创建文件,例如:
b786af1_original_name.ABC
a7af335_original_name_2.ABC
...
上面的命令显然无法工作,因为$(...)语句被求值一次。我需要对每个文件名进行评估。 怎么做?     
已邀请:
为什么不读书?
find /tmp -name \\*.ABC | while read i; do cp $i $(basename $i | md5sum | cut -c1-6)$(basename $i); done;
    
基于当前纳秒的随机整数怎么样?
date +%N | sed -e \'s/000$//\' -e \'s/^0//\'
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#  Strip off leading and trailing zeroes, if present.
#  Length of generated integer depends on
#  + how many zeroes stripped off.
使用此方法获得具有相同名称的相同文件的可能性很小。 资料来源:http://tldp.org/LDP/abs/html/timedate.html 编辑:实际上,这只会给您同样的问题。它需要成为一个班轮吗?     
作为记录,这是@Ken答案的怪异文件名版本:
find /tmp -name \\*.ABC -print0 | while IFS= read -r -d $\'\\0\' i; do cp \"$i\" \"$(basename \"$i\" | md5sum | cut -c1-6)$(basename \"$i\")\"; done
有关详细信息,变体等,请参见BashFAQ#20。     
使用ѭ5生成唯一名称:
find /tmp -name \\*.ABC | while read f; do 
  cp \"$f\" \"$(mktemp /destination/dir/XXXXXXXXXX.ABC)\"
done
    
重要的旁注:请注意您正在使用哈希作为标识符的一部分。 如果您使用的是0..F(6个值)的6个值,则该组合少于1700万个组合。因此,如果您要使用这些文件标识5000个文件,则发生冲突的机会为52%。 7个十六进制字符占4.5%,而8个十六进制字符占0.3%的碰撞(对于5000个文件)。     

要回复问题请先登录注册