Список аргументов слишком длинный - Unix - PullRequest
8 голосов
/ 31 июля 2011

Эти сценарии сортируют файлы по дате, а затем перемещают первые 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 ]

3 голосов
/ 31 июля 2011

Вы не сказали, но я предполагаю, что именно здесь возникает проблема:

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, поэтому шаблон выглядит немного иначе.)

2 голосов
/ 31 июля 2011

Изменение

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 для создания списка файлов с метками времени модификации, сортировки по метке времени, а затем удаляет ненужное поле перед передачей вывода в head и xargs

EDIT

Другой вариант, должен работать без утилит 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"
1 голос
/ 31 июля 2011

Сначала создайте резервный список файлов, которые нужно обработать. Затем прочитайте файл резервной копии построчно и вылечите его. Например

 #!/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
0 голосов
/ 31 июля 2011

Быстрый способ исправить это - это изменить значение на $ FROM_DIRECTORY, чтобы вы могли ссылаться на файлы, используя (более короткие) относительные пути.

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

Это также неабсолютно надежно, если у вас слишком много подходящих файлов.

...