参数列表太长 – Unix

这个脚本将按date对文件进行sorting,然后将第一批2500个文件移到另一个目录。
当我运行下面的脚本,系统提示出参数列表太长味精。 任何人都可以帮助我提高脚本? 谢谢

NUM_OF_FILES=2500 FROM_DIRECTORY=/apps/data01/RAID/RC/MD/IN_MSC/ERC/in DESTINATION_DIRECTORY=/apps/data01/RAID/RC/MD/IN_MSC/ERC/in_load if [ ! -d $DESTINATION_DIRECTORY ] then echo "unused_file directory does not exist!" mkdir $DESTINATION_DIRECTORY echo "$DESTINATION_DIRECTORY directory created!" else echo "$DESTINATION_DIRECTORY exist!" fi echo "Moving $NUM_OF_FILES oldest files to $DESTINATION_DIRECTORY directory" ls -tr $FROM_DIRECTORY/MSCERC*.Z|head -$NUM_OF_FILES | xargs -i sh -c "mv {} $DESTINATION_DIRECTORY" 

你没有说,但我认为这是问题发生的地方:

 ls -tr $FROM_DIRECTORY/MSCERC*.Z|head -2500 | \ xargs -i sh -c "mv {} $DESTINATION_DIRECTORY" 

(您可以通过在脚本的顶部添加“set -x”来验证它。)

问题是内核有一个固定的最大大小的命令行的总长度给一个新的进程,你超过了在ls命令。 你可以通过不使用globbing来代替使用grep

 ls -tr $FROM_DIRECTORY/ | grep '/MSCERC\*\.Z$' |head -2500 | \ xargs -i sh -c "mv {} $DESTINATION_DIRECTORY" 

grep使用正则表达式而不是globs,所以模式看起来有些不同。)

更改

 ls -tr $FROM_DIRECTORY/MSCERC*.Z|head -2500 | \ xargs -i sh -c "mv {} $DESTINATION_DIRECTORY" 

做如下的事情:

 find "$FROM_DIRECTORY" -maxdepth 1 -type f -name 'MSCERC*.Z' -printf '%p\t%T@\n' | sort -k2,2 -r | cut -f1 | head -$NUM_OF_FILES | xargs mv -t "$DESTINATION_DIRECTORY" 

这使用find来创建具有修改时间戳的文件列表,按照时间戳进行排序,然后在将输出传递给headxargs之前删除不需要的字段

编辑

另一个变体,应该与非GNU实用程序一起工作

 find "$FROM_DIRECTORY" -type f -name 'MSCERC*.Z' -printf '%p\t%T@' |sort -k 2,2 -r | cut -f1 | head -$NUM_OF_FILES | xargs -i mv \{\} "$DESTINATION_DIRECTORY" 

首先创建要处理的文件的备份列表。 然后逐行读取备份文件并修复它。 例如

  #!/bin/bash NUM_OF_FILES=2500 FROM_DIRECTORY=/apps/data01/RAID/RC/MD/IN_MSC/ERC/in DESTINATION_DIRECTORY=/apps/data01/RAID/RC/MD/IN_MSC/ERC/in_load if [ ! -d $DESTINATION_DIRECTORY ] then echo "unused_file directory does not exist!" mkdir $DESTINATION_DIRECTORY echo "$DESTINATION_DIRECTORY directory created!" else echo "$DESTINATION_DIRECTORY exist!" fi echo "Moving $NUM_OF_FILES oldest files to $DESTINATION_DIRECTORY directory" ls -tr $FROM_DIRECTORY/MSCERC*.Z|head -2500 > list exec 3<list while read file <&3 do mv $file $DESTINATION_DIRECTORY done 

解决这个问题的一个快速方法是更改​​为$ FROM_DIRECTORY,以便可以使用(较短的)相对路径来引用文件。

cd $FROM_DIRECTORY && ls -tr MSCERC*.Z|head -2500 |xargs -i sh -c "mv {} $DESTINATION_DIRECTORY"

如果你有太多的文件匹配,这也不是完全的傻瓜。