参数列表太长 - Unix

时间:2011-07-31 16:15:46

标签: bash unix scripting sh

此脚本将按日期对文件进行排序,然后将前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"  

4 个答案:

答案 0 :(得分:3)

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

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,因此模式看起来有点不同。)

答案 1 :(得分:2)

更改

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 utils一起使用

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"

答案 2 :(得分:1)

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

 #!/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

答案 3 :(得分:0)

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

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

如果您有太多匹配的文件,这也不是完全万无一失。