پرسش و پاسخ شماره ۵۶ - آموزش اسکریپت نویسی
X
تبلیغات
رایتل

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

#!/bin/bash

پرسش و پاسخ شماره ۵۶

پرسش و پاسخ شماره ۵۶

چطور می‌توانم چند فایل را به طور یکجا untar (یا unzip) نمایم؟

چون فرمان tar در اصل طوری طراحی شده بود که از دستگاه‌های نوار گردان مغناطیسی بخواند یا در آن بنویسد(کلمه tar از ‎ Tape ARchiver‎ اخذ شده)، شما به طور خاص فقط می‌توانید نام فایلها را در بایگانی قرار دهید(نوشتن در نوار) یا آنها را از یک آرشیو استخراج نمایید(خواندن از نوار).

یک گزینه وجود دارد که به tar می‌گوید آرشیو روی نوار مغناطیسی نیست، بلکه در یک فایل است: ‎-f‎. این گزینه دقیقاً یک شناسه می‌پذیرد: نام فایل محتوی آرشیو. تمام نام فایلهای دیگر(در ادامه) به عنوان اعضاء آرشیو در نظر گرفته می‌شوند:

    tar -x -f backup.tar myfile.txt
    # ( IMHO یا(ترکیب دستوری عمومی‌تر
    tar xf backup.tar myfile.txt

حال در اینجا یک اشتباه رایج هست -- تصور کنید دایرکتوری شامل فایلهای بایگانی زیر است و می‌خواهید همه را به یکباره استخراج کنید:

    $ ls
    backup1.tar backup2.tar backup3.tar

شاید فکر کنید با دستور ‎ tar xf *.tar‎ انجام بدهید. بیایید ببینیم:

    $ tar xf *.tar
    tar: backup2.tar: Not found in archive
    tar: backup3.tar: Not found in archive
    tar: Error exit delayed from previous errors

جه اتفاقی رخ می‌دهد؟ پوسته ‎ *.tar‎ شما را با فایلهای قابل انطباق تعویض می‌کند. در حقیقت شما نوشته‌اید:

    tar xf backup1.tar backup2.tar backup3.tar

و به طوری که فبلاً دیدیم، به معنی آنست که: «فایلهای backup2.tar و backup3.tar را از فایل بایگانی backup1.tar استخراج کن», که البته فقط موقعی موفق خواهد شد که چنین نام فایلهایی در فایل بایگانی ذخیره شده باشند.

راه حل نسبتاً آسان است: استخراج محتویات تمام آرشیوها به طور یکی یکی. چنانچه ما از شل یونیکس استفاده می‌کنیم و تنبل هستیم، با یک حلقه آن کار را انجام می‌دهیم:

    for tarname in ./*.tar; do
      tar xf "$tarname"
    done

چه اتفاقی می‌افتد؟ حلقه for روی تمام نام فایلها که با ‎ *.tar‎ منطبق می‌شوند تکرار می‌کند و ‎ tar xf را برای هر یک از آنها فرامی‌خواهد. به این طریق شما تمام فایلهای بایگانی را یک به یک استخراج می‌کنید و درست آن را به طور خودکار انجام می‌دهید.

دومین نوع آرشیو رایج در این روزها ZIP است. فرمان unzip برای استخراج محتویات از یک فایل ZIP است(چه کسی آن را پیشنهاد کرده است!). مشکل در اینجا خیلی مشابه است: unzip فقط یک گزینهِ تعیین کننده فایل ZIP را می‌پذیرد. بنابراین، آن را به همان روش حل کنید:

    for zipfile in ./*.zip; do
      unzip "$zipfile"
    done

کافی نیست؟ Ok. گزینه دیگری همراه unzip وجود دارد: این گزینه می‌تواند الگوهای شل-مانند را برای تعیین نام فایلهای ZIP قبول کند. و برای پرهیز از تفسیر آن الگوها توسط پوسته، لازم است آنها را نقل‌قولی کنید. در این حالت خود unzip و نه پوسته، عبارت ‎ *.zip‎ را تفسیر می‌کند:

    unzip "*.zip"
    # :یا برای شفاف کردن آن که چه کار می‌کنیم 
    unzip \*.zip

(این ویژگی دستور unzip در اصل از خاستگاه آن به عنوان یک برنامه MS-DOS ناشی می‌گردد. مفسر فرمان MS-DOS بسط‌های glob انجام نمی‌دهد، بنابراین هر برنامه MS-DOS باید قادر باشد فوق کاراکترها را به لیستی از نام فایلها بسط بدهد. این ویژگی در نگارش یونیکس باقی گذاشته شد، و به طوری که نمایش دادیم، گاهی اوقات می‌تواند مفید باشد.)


CategoryShell

پرسش و پاسخ 56 (‎ 2011-02-11 19:26:45 ‎ توسط GreyCat)