หลักฐาน
คุณไม่ควรเกิดขึ้นจากข้อผิดพลาดที่สำหรับเพียง 15k ไฟล์ที่มีรูปแบบเฉพาะชื่อที่[ 1 , 2 ]
หากคุณใช้ส่วนขยายนั้นจากไดเรกทอรีอื่นและคุณต้องเพิ่มเส้นทางไปยังแต่ละไฟล์ขนาดของคำสั่งของคุณจะใหญ่ขึ้นและแน่นอนว่ามันอาจเกิดขึ้นได้
โซลูชันเรียกใช้คำสั่งจากไดเรกทอรีนั้น
(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )
ทางออกที่ดีที่สุดถ้าฉันเดาไม่ดีและคุณเรียกใช้จากไดเรกทอรีที่เป็นไฟล์ ...
IMHO ทางออกที่ดีที่สุดคือStéphane Chazelas ' ;
seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb
ด้วย printf หรือ seq; ทดสอบกับไฟล์ 15k ที่มีเฉพาะหมายเลขภายในแคชล่วงหน้าเท่านั้นแม้จะเป็นไฟล์ที่เร็วกว่า (ปัจจุบันและยกเว้นไฟล์ OP หนึ่งไฟล์จากไดเรกทอรีเดียวกันกับไฟล์ที่มีอยู่)
บางคำเพิ่มเติม
คุณควรส่งผ่านไปยังบรรทัดคำสั่งเชลล์ของคุณได้นานขึ้น
บรรทัดคำสั่งของคุณคือ 213914 ตัวอักษรและมีความยาว 1,5003 คำ
cat file_{1..15000}.pdb " > file_all.pdb" | wc
... แม้แต่การเพิ่ม 8 ไบต์สำหรับแต่ละคำคือ 333 938 ไบต์ (0.3M) ด้านล่างจาก 2097142 (2.1M) ที่รายงานโดยARG_MAX
เคอร์เนล 3.13.0 หรือ 2088232 ที่มีขนาดเล็กกว่าเล็กน้อยรายงานว่า"ความยาวสูงสุดของคำสั่งที่เราสามารถทำได้จริง ใช้ "โดยxargs --show-limits
ให้มันดูในระบบของคุณเพื่อการส่งออกของ
getconf ARG_MAX
xargs --show-limits
แนวทางแก้ปัญหาความขี้เกียจ
ในกรณีเช่นนี้ฉันชอบที่จะทำงานกับบล็อกเพราะมักจะเป็นทางออกที่มีประสิทธิภาพเวลา
ตรรกะ (ถ้ามี) คือฉันขี้เกียจเขียน 1 ... 1,000 1001..2000 ฯลฯ ฯลฯ ...
ดังนั้นฉันจึงขอให้สคริปต์ทำเพื่อฉัน
หลังจากฉันตรวจสอบผลลัพธ์แล้วความถูกต้องฉันเปลี่ยนเส้นทางไปยังสคริปต์
... แต่ความเกียจคร้านเป็นสภาวะของจิตใจ
เนื่องจากฉันแพ้xargs
(ฉันควรใช้xargs
ที่นี่จริง ๆ) และฉันไม่ต้องการตรวจสอบวิธีการใช้ฉันจึงเสร็จสิ้นการคิดค้นล้อให้ตรงเวลาตามตัวอย่างด้านล่าง (tl; dr)
โปรดทราบว่าเนื่องจากชื่อไฟล์ถูกควบคุม (ไม่มีช่องว่าง, บรรทัดใหม่ ... ) คุณสามารถไปได้อย่างง่ายดายด้วยบางสิ่งบางอย่างเช่นสคริปต์ด้านล่าง
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
โทรทุบตีเพื่อขยาย (ช้าลงเล็กน้อยในการทดสอบของฉัน ~ 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 ] ...