Öncül
Bu hataya yalnızca belirli ad biçimine sahip 15 bin dosya için girmemelisiniz [ 1 , 2 ] .
Bu genişletmeyi başka bir dizinden çalıştırıyorsanız ve her dosyaya yol eklemeniz gerekiyorsa, komutunuzun boyutu daha büyük olur ve elbette oluşabilir.
Çözüm bu dizinden komutu çalıştırın.
(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )
En iyi çözüm Bunun yerine kötü tahmin ve eğer dosyaları olduğu dizinden çalıştırın ...
IMHO en iyi çözüm Stéphane Chazelas 'olanlar :
seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb
printf veya seq ile; sadece önbellek içindeki numaraları ile 15k dosyalarda test daha hızlı olanı (şu anda ve dosyaları aynı dizinden OP biri hariç).
Bazı kelimeler daha
Kabuk komut satırlarınıza daha uzun süre geçebilmelisiniz.
Komut satırınız 213914 karakter uzunluğunda ve 15003 kelime içeriyor
cat file_{1..15000}.pdb " > file_all.pdb" | wc
... her kelime için 8 bayt eklemek bile, 3.13.0 ARG_MAX
çekirdeğinde veya biraz daha küçük 2088232'de "Gerçekte yapabileceğimiz maksimum komut uzunluğu" tarafından "kullan"xargs --show-limits
Sisteminizin çıktısına sisteminize bir göz atın
getconf ARG_MAX
xargs --show-limits
Tembellik rehberli çözüm
Bu gibi durumlarda, genellikle zaman etkili bir çözüm çıktığı için bloklarla çalışmayı tercih ederim.
Mantık (eğer varsa) 1 ... 1000 1001..2000 vs yazmak için çok tembelim ...
Yani bir senaryoyu benim için yapmasını istiyorum.
Yalnızca çıktı doğruluğunu kontrol ettikten sonra bir betiğe yönlendiriyorum.
... ama Tembellik bir ruh halidir .
Alerjim olduğu için xargs
(gerçekten xargs
burada kullanmalıydım) ve nasıl kullanılacağını kontrol etmek istemiyorum, aşağıdaki örneklerde olduğu gibi tekerleği yeniden icat etmek için zamanında bitiriyorum (tl; dr).
Dosya adları kontrol edildiğinden (boşluk yok, yeni satırlar ...) aşağıdaki komut dosyası gibi bir şeyle kolayca gidebileceğinizi unutmayın.
tl; Dr.
Sürüm 1: isteğe bağlı parametre olarak 1. dosya numarası, son, blok boyutu, çıktı dosyası
#!/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;
Versiyon 2
Genişleme için bash çağrılıyor (testlerimde biraz daha yavaş ~% 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;
Tabii ki ileri gidip seq
[ 3 ] 'den (coreutils'ten) tamamen kurtulabilir ve doğrudan bash değişkenleriyle çalışabilir veya python kullanabilir veya bunu yapmak için ac programını derleyebilirsiniz [ 4 ] ...