Prämisse
Dieser Fehler sollte nicht bei nur 15.000 Dateien mit diesem bestimmten Namensformat auftreten [ 1 , 2 ] .
Wenn Sie diese Erweiterung in einem anderen Verzeichnis ausführen und den Pfad zu jeder Datei hinzufügen müssen, ist der Umfang Ihres Befehls größer und kann natürlich auftreten.
Lösung führen Sie den Befehl aus diesem Verzeichnis.
(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )
Beste Lösung Wenn ich stattdessen schlecht geraten habe und Sie es aus dem Verzeichnis ausführen, in dem sich die Dateien befinden ...
IMHO ist die beste Lösung die von Stéphane Chazelas :
seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb
mit printf oder seq; Getestet mit 15k-Dateien, bei denen nur deren Nummer im Cache gespeichert ist, ist dies sogar die schnellere (derzeit und mit Ausnahme der OP-Datei aus demselben Verzeichnis, in dem sich die Dateien befinden).
Noch ein paar Worte
Sie sollten in der Lage sein, Ihre Shell-Befehlszeilen länger zu übergeben.
Ihre Befehlszeile ist 213914 Zeichen lang und enthält 15003 Wörter
cat file_{1..15000}.pdb " > file_all.pdb" | wc
... sogar das Hinzufügen von 8 Bytes für jedes Wort liegt 333.938 Bytes (0,3 MB) weit unter dem Wert von 2097142 (2,1 MB), der von ARG_MAX
einem Kernel 3.13.0 oder dem geringfügig kleineren Wert von 2088232 gemeldet wurde, der als "Maximale Befehlslänge, die wir tatsächlich erreichen könnten" angegeben wurde use " vonxargs --show-limits
Sehen Sie sich die Ausgabe von auf Ihrem System an
getconf ARG_MAX
xargs --show-limits
Laziness geführte Lösung
In solchen Fällen arbeite ich am liebsten mit Blöcken, auch weil sich in der Regel eine zeitsparende Lösung ergibt.
Die Logik (falls vorhanden) ist, dass ich viel zu faul bin, um 1 ... 1000 1001..2000 usw. usw. zu schreiben.
Deshalb bitte ich ein Skript, dies für mich zu tun.
Erst nachdem ich die Ausgabe auf Korrektheit überprüft habe, leite ich sie in ein Skript um.
... aber Faulheit ist ein Geisteszustand .
Da ich allergisch gegen xargs
(ich hätte es xargs
hier wirklich verwenden sollen ) bin und nicht prüfen wollen, wie ich es benutze, beende ich die Neuerfindung des Rads pünktlich wie in den folgenden Beispielen (tl; dr).
Da die Dateinamen kontrolliert werden (keine Leerzeichen, Zeilenumbrüche ...), können Sie problemlos mit dem folgenden Skript arbeiten.
tl; dr
Version 1: Übergeben Sie als optionalen Parameter die 1. Dateinummer, die letzte, die Blockgröße und die Ausgabedatei
#!/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
Aufruf von bash für die Erweiterung (in meinen Tests etwas langsamer ~ 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;
Natürlich können Sie seq
[ 3 ] (von coreutils) loswerden und direkt mit den Variablen in bash arbeiten oder Python verwenden oder ein Programm kompilieren, um dies zu tun [ 4 ] ...