посылка
Вы не должны подвергаться этой ошибке только для файлов 15k с определенным форматом имени [ 1 , 2 ] .
Если вы запускаете это расширение из другого каталога и вам нужно добавить путь к каждому файлу, размер вашей команды будет больше, и, конечно, это может произойти.
Решение запустить команду из этого каталога.
(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )
Лучшее решение Если вместо этого я угадал, и вы запускаете его из каталога, в котором находятся файлы ...
ИМХО, лучшее решение - это Стефан Шазелас :
seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb
с printf или seq; протестировано на 15k файлах, в которых предварительно кэшировано только их число, оно даже быстрее (в настоящее время, за исключением OP из того же каталога, в котором находятся файлы).
Еще несколько слов
Вы должны быть в состоянии передавать командную строку вашей оболочки более долго.
Длина вашей командной строки составляет 213914 символов и содержит 15003 слова
cat file_{1..15000}.pdb " > file_all.pdb" | wc
... даже добавление 8 байт для каждого слова составляет 333 938 байт (0,3 М), намного ниже, чем 2097142 (2,1 МБ), о которых сообщалось ARG_MAX
в ядре 3.13.0 или немного меньшем 2088232, о котором сообщалось как "Максимальная длина команды, которую мы могли бы на самом деле использовать " поxargs --show-limits
Посмотрите на вашу систему на вывод
getconf ARG_MAX
xargs --show-limits
Решение для лени
В таких случаях я предпочитаю работать с блоками даже потому, что, как правило, получается эффективное по времени решение.
Логика (если есть) в том, что я слишком ленив, чтобы писать 1 ... 1000 1001..2000 и т. Д.
И т. Д. Поэтому я прошу сценарий сделать это для меня.
Только после того, как я проверил правильность вывода, я перенаправил его в скрипт.
... но лень это состояние души .
Поскольку у меня аллергия на xargs
(я действительно должен был использовать xargs
здесь), и я не хочу проверять, как его использовать, я заканчиваю пунктуально, чтобы заново изобрести колесо, как в примерах ниже (tl; dr).
Обратите внимание, что, поскольку имена файлов контролируются (без пробелов, новых строк ...), вы можете легко выполнить что-то вроде приведенного ниже сценария.
ТЛ; др
Версия 1: передать в качестве необязательного параметра 1-й номер файла, последний, размер блока, выходной файл
#!/bin/bash
StartN=${1:-1} # First file number
EndN=${2:-15000} # Last file number
BlockN=${3:-100} # files in a Block
OutFile=${4:-"all.pdb"} # Output file name
CurrentStart=$StartN
for i in $(seq $StartN $BlockN $EndN)
do
CurrentEnd=$i ;
cat $(seq -f file_%.17g.pdb $CurrentStart $CurrentEnd) >> $OutFile;
CurrentStart=$(( CurrentEnd + 1 ))
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] &&
cat $(seq -f file_%.17g.pdb $CurrentStart $EndN) >> $OutFile;
Версия 2
Вызов bash для расширения (немного медленнее в моих тестах ~ 20%).
#!/bin/bash
StartN=${1:-1} # First file number
EndN=${2:-15000} # Last file number
BlockN=${3:-100} # files in a Block
OutFile=${4:-"all.pdb"} # Output file name
CurrentStart=$StartN
for i in $(seq $StartN $BlockN $EndN)
do
CurrentEnd=$i ;
echo cat file_{$CurrentStart..$CurrentEnd}.pdb | /bin/bash >> $OutFile;
CurrentStart=$(( CurrentEnd + 1 ))
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] &&
echo cat file_{$CurrentStart..$EndN}.pdb | /bin/bash >> $OutFile;
Конечно, вы можете пойти дальше и полностью избавиться от seq
[ 3 ] (от coreutils) и работать напрямую с переменными в bash, или использовать python, или скомпилировать программу ac для этого [ 4 ] ...