الأنابيب متعددة الملفات (GZ) في برنامج C
سؤال
لقد كتبت برنامج C يعمل عندما أقوم بإنصاف البيانات في برنامجي باستخدام stdin مثل:
gunzip -c IN.gz|./a.out
إذا أردت تشغيل برنامجي على قائمة الملفات ، يمكنني أن أفعل شيئًا مثل:
for i `cat list.txt`
do
gunzip -c $i |./a.out
done
ولكن هذا سيبدأ عدد أوقات برنامج الملفات الخاصة بي. أنا مهتم بإنقاذ جميع الملفات في نفس العملية.
مثل القيام
for i `cat list.txt`
do
gunzip -c $i >>tmp
done
cat tmp |./a.out
كيف يمكنني أن أفعل هذا؟
المحلول
ليست هناك حاجة لحلقة قذيفة:
gzip -cd $(<list.txt) | ./a.out
مع ال '-cd
"الخيار ، ستقوم GZIP بفصل قائمة الملفات إلى الإخراج القياسي (أو يمكنك استخدامها"gunzip -c
'). ال $(<file)
يوسع تدوين محتويات الملف المسماة كقائمة من الوسائط دون إطلاق عملية فرعية. يعادل $(cat list.txt)
غير ذلك.
ومع ذلك ، إذا شعرت أنه يجب عليك استخدام حلقة ، فما عليك سوى تنشيط الإخراج من الحلقة إلى مثيل واحد لبرنامجك:
for i in `cat list.txt`
do
gunzip -c $i
done |
./a.out
إذا كانت محتويات الحلقة أكثر تعقيدًا (من مجرد تحريك ملف واحد) ، فقد يكون ذلك ضروريًا. تستطيع ايضا استخذام '{ ... }
إعادة توجيه I/O:
{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
gunzip -c $i
done
} |
./a.out
أو:
{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
gunzip -c $i
done; } |
./a.out
لاحظ نصف كولون. إنه ضروري مع الأقواس. في هذا المثال ، هو في الأساس استخدام قشرة فرعية رسمية مع أقواس:
(
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
gunzip -c $i
done
) |
./a.out
أو:
( cat /etc/passwd /etc/group
for i in `cat list.txt`
do
gunzip -c $i
done) |
./a.out
لاحظ عدم وجود شبه كولون هنا ؛ ليس هناك حاجة. القشرة مرتاح بشكل رائع في بعض الأحيان. يمكن أن تكون إعادة توجيه الأقواس I/O مفيدة عندما تحتاج إلى تجميع أوامر بعد رمز الأنابيب:
some_command arg1 arg2 |
{
first sub-command
second command
for i in $some_list
do
...something with $i...
done
} >$outfile 2>$errfile
نصائح أخرى
يجب أن تكون قادرًا على الحصول على واحدة gunzip
معالجة ملفات ملفات متعددة.
zcat $(cat list.txt) | ./a.out
(zcat
هي طريقة أخرى للاتصال gunzip -c
على العديد من الأنظمة ويظهر بالتوازي مع cat
; ؛ ولكن تحقق من gzcat
إذا كان نظامك zcat
هو في الواقع uncompress
.)
بدلاً من ذلك ، يمكنك استخدام قذيفة فرعية.
(
for i in $(cat list.txt)
do
gunzip -c "$i"
done
) | ./a.out
هذا هو بالأحرى سؤال قذيفة. لكن Afaik يمكنك القيام به:
cat file* | your_program
أو
for i in file*; do gunzip -c $i; done | your_program
Xargs هو صديقك
٪ cat list.txt | Xargs Gunzip -C | ./A.out
إذا كانت الملفات الموجودة في list.txt تحتوي على مسافات فيها ، فأنت بحاجة إلى المرور من خلال بعض الأطواق الإضافية.
إذا لم يكن برنامجك بحاجة إلى معرفة متى ينتهي إدخال معين ويبدأ آخر ، فيمكنك القيام بذلك:
for i `cat list.txt`
do
gunzip -c $i
done |./a.out
آمل أن يساعدك