سؤال

لقد كتبت برنامج 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

آمل أن يساعدك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top