Prémisse
Vous ne devriez pas encourir cette erreur pour seulement 15 000 fichiers avec ce format de nom spécifique [ 1 , 2 ] .
Si vous exécutez cette extension à partir d'un autre répertoire et que vous devez ajouter le chemin d'accès à chaque fichier, la taille de votre commande sera plus grande et, bien sûr, cela peut se produire.
Solution exécutez la commande à partir de ce répertoire.
(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )
Meilleure solution Si à la place j'ai deviné mauvais et que vous l'exécutez à partir du répertoire dans lequel se trouvent les fichiers ... À
mon humble avis, la meilleure solution est celle de Stéphane Chazelas :
seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb
avec printf ou seq; testé sur des fichiers 15k avec seulement leur nombre à l'intérieur pré-mis en cache, il est même le plus rapide (à l'heure actuelle et à l'exception de l'OP du même répertoire dans lequel se trouvent les fichiers).
Quelques mots de plus
Vous devriez pouvoir passer à vos lignes de commande shell plus longtemps.
Votre ligne de commande contient 213914 caractères et contient 15003 mots
cat file_{1..15000}.pdb " > file_all.pdb" | wc
... même l'ajout de 8 octets pour chaque mot est 333 938 octets (0,3 M) bien en deçà du 2097142 (2,1 M) rapporté par ARG_MAX
sur un noyau 3.13.0 ou du 2088232 légèrement plus petit rapporté comme "Longueur maximale de commande que nous pourrions réellement utiliser " parxargs --show-limits
Donnez un aperçu de votre système à la sortie de
getconf ARG_MAX
xargs --show-limits
Solution guidée paresse
Dans des cas comme celui-ci, je préfère travailler avec des blocs, même parce que généralement une solution efficace en temps.
La logique (le cas échéant) est que je suis beaucoup trop paresseux pour écrire 1 ... 1000 1001..2000 etc etc ...
Je demande donc à un script de le faire pour moi.
Ce n'est qu'après avoir vérifié que la sortie est correcte que je la redirige vers un script.
... mais la paresse est un état d'esprit .
Comme je suis allergique à xargs
(j'aurais vraiment dû l'utiliser xargs
ici) et que je ne veux pas vérifier comment l'utiliser, je termine ponctuellement pour réinventer la roue comme dans les exemples ci-dessous (tl; dr).
Notez que puisque les noms de fichiers sont contrôlés (pas d'espaces, de nouvelles lignes ...), vous pouvez aller facilement avec quelque chose comme le script ci-dessous.
tl; dr
Version 1: passez en paramètre optionnel le 1er numéro de fichier, le dernier, la taille du bloc, le fichier de sortie
#!/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;
Version 2
Appel bash pour l'expansion (un peu plus lent dans mes tests ~ 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;
Bien sûr, vous pouvez aller de l'avant et vous débarrasser complètement de seq
[ 3 ] (de coreutils) et travailler directement avec les variables dans bash, ou utiliser python, ou compiler un programme ac pour le faire [ 4 ] ...