منبع اصلی نوشتار زیر در این لینک قرار دارد

فصل مشترک یا تفاوت دو فایل


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

چطور می‌توانم تمام سطرهایی را به دست آورم که: در هر دو فایل هستند(فصل مشترک) یا فقط در یکی از دوفایل می‌باشند(تفاوتها).

از فرمان‎ comm(1)‎ استفاده کنید:

# Bash
#  file2 و file1 فصل مشترک‎
# (یعنی فقط سطرهایی که در هر دو فایل وجود دارد)‎
comm -12 <(sort file1) <(sort file2)

#  file2 از file1 تفریق ‎
# (وجود دارد file2 یعنی سطرهایی که منحصراً در)‎
comm -13 <(sort file1) <(sort file2)

برای تفصیل بیشتر صفحات man دستور comm را بخوانید. آنها که آن بالا می‌بینید جایگزینی پردازش‌ها هستند.

اگر بنا به دلایلی سیستم شما فاقد برنامه مرکزی comm است، می‌توانید از این روشهای دیگر استفاده کنید. (در حقیقت، شما از هیچ کدام اینها واقعاً نباید استفاده کنید. این روشها توسط افرادی نوشته شده‌اند که هنوز چیزی در باره comm نمی‌دانستند. اما پیشنهادات محرمانه برای دوستداران کُندی!)

  1. یک پیاده‌سازی ساده و سریع شگفت آور، فقط در 20 ثانیه مطابقت فایل به اندازه‎ 30k ‎با فایلی با سطرهایی به اندازه ‎ 400k‎ را برای من انجام داد.
      #  file2 و file1 فصل مشترک‎
      grep -xF -f file1 file2
    
      #  file2 از file1 تفریق‎
      grep -vxF -f file1 file2
    • grep یکی از مجموعه‌ها را به عنوان لیست الگو از فایل‎ (-f)‎ می‌خواند، و الگوها را به عنوان یک رشته ساده نه عبارتهای منظم‎ (-F)‎ تفسیر می‌کند، مطابقت فقط با کل سطر‎ (-x)‎ انجام می‌شود.
    • توجه نمایید که فایل مشخص شده با ‎ -f‎ در حافظه بارگذاری خواهد شد، بنابراین برای فایلهای خیلی بزرگ معیار نیست.
    • این کُد با هر grep سازگار با POSIX کار خواهد کرد، در سیستم‌های قدیمی‌تر ممکن است به جای ‎grep -F‎ نیاز به استفاده از fgrep داشته باشید.

  2. یک پیاده‌سازی با استفاده از sort و uniq:
      #  file2 و file1 فصل مشترک‎
      sort file1 file2 | uniq -d  # (با این فرض که فایلها محتویات تکراری ندارند)‎
    
      # file1-file2 (تفریق)
      sort file1 file2 file2 | uniq -u
    
      # file2 - file1 (تفریق به همان طریق اما برعکس)‎
      sort file1 file2 file1 | uniq -u
  3. یک پیاده سازی دیگر برای تفریق:
      sort file1 file1 file2 | uniq -c |
      awk \'{ if ($1 == 2) { $1 = ""; print; } }\'
    • این شاید یک فاصله اضافی در ابتدای سطر وارد کند، اگر این مسئله است، آن فاصله را حذف کنید.
    • همچنین، این رویکرد فرض می‌کند که نه file1 و نه file2 سطر تکراری ندارند.
    • سرانجام، این خروجی را برای شما مرتب می‌کند. اگر این مسئله است، آنوقت شما به طورکلی این رویکرد را رها کنید. شاید بتوانید از آرایه‌های انجمنی awk به جای آن استفاده کنید(یا از hashهای پرل یا آرایه‌های tcl).
  4. این مثالها تفریق و فصل مشترک با awk هستند، صرف نظر از اینکه فایلهای ورودی مرتب شده یا دارای محتویات تکراری باشند:
      #   .نیستند را چاپ می‌کند file2 هستند و در file1 فقط سطرهایی که در‎
      #   .با جابه جایی شناسه‌ها نتیجه معکوس خواهید گرفت‎
      awk \'NR==FNR{a[$0];next} !($0 in a)\' file2 file1
    
      #   .سطرهایی که در هر دو فایل هستند چاپ می‌شود، ترتیب شناسه‌ها مهم نیست
      awk \'NR==FNR{a[$0];next} $0 in a\' file1 file2

    برای یک شرح در باره چگونگی کارکرد این مورد، مقایسه دو فایل توسط awk را ببینید.

See Also

http://www.pixelbeat.org/cmdline.html#sets


CategoryShell

پرسش و پاسخ 36 (آخرین ویرایش ‎ 2010-12-28 17:17:57 ‎ توسط GreyCat)




به سیاره لینوکس امتیاز دهید

به اين صفحه امتياز دهيد