سرورلینوکس

تسلط بر grep با عبارات باقاعده برای جستجوی کارآمد متن

مقدمه

دستور grep یکی از پرکاربردترین دستورات در محیط ترمینال لینوکس است. نام grep مخفف عبارت «global regular expression print» است. یعنی می‌توانید از grep برای بررسی اینکه آیا ورودیِ دریافتی‌اش با یک الگوی مشخص مطابقت دارد یا نه استفاده کنید. این برنامه که در نگاه اول ساده به نظر می‌رسد، فوق‌العاده قدرتمند است؛ توانایی‌اش در فیلتر کردن ورودی بر اساس قوانین پیچیده، آن را به حلقه‌ای محبوب در بسیاری از زنجیره‌های دستور تبدیل کرده است.

در این آموزش، استفاده از grep همراه با عبارات باقاعده (Regular Expressions) را برای جستجوی کارآمد متن از پایه تا تکنیک‌های پیشرفته یادتان می‌دهیم. با تطبیق تحت‌اللفظی پایه شروع می‌کنیم و رایج‌ترین گزینه‌های خط فرمان grep را برای دقیق‌تر کردن جستجوها بررسی می‌کنیم. سپس ساخت الگوهای قدرتمند جستجو را یاد می‌گیرید؛ ابتدا عبارات باقاعده پایه برای تطبیق الگوی مقدماتی، بعد به عبارات باقاعده گسترش‌یافته انعطاف‌پذیرتر و عبارات باقاعده سازگار با پرل (PCRE) پرامکانات می‌رسیم که امکان جستجوهای پیچیده‌تر و دقیق‌تری فراهم می‌کنند. برای تثبیت درک‌تان، مثال‌های عملی و واقعی را مرور می‌کنیم و با ملاحظات کارایی به پایان می‌رسیم تا بتوانید دستوراتتان را برای سرعت و بهره‌وری بهینه کنید.

نکات کلیدی

  • دستور grep که مخفف «global regular expression print» است، بررسی می‌کند که آیا ورودی دریافتی‌اش با یک الگوی مشخص مطابقت دارد یا نه.
  • گزینه‌های رایج شامل -i برای بی‌توجهی به بزرگی و کوچکی حروف، -v برای پیدا کردن خطوطی که الگو را ندارند و -n برای نمایش شماره خطوط مطابقت‌یافته است.
  • لنگرها (Anchor) کاراکترهای خاصی هستند که مشخص می‌کنند تطبیق باید کجا اتفاق بیفتد؛ مثل ^ برای ابتدای خط و $ برای انتهای خط.
  • عبارات براکتی ([]) می‌توانند با هر یک از کاراکترهای یک گروه مشخص مطابقت پیدا کنند، در حالی که نقطه (.) با هر کاراکتر منفردی تطبیق می‌یابد.
  • وقتی می‌خواهید کاراکتری را جستجو کنید که در عبارات باقاعده معنای خاصی دارد، باید آن را با بک‌اسلش (\) «escape» کنید.
  • فلگ -E یا دستور egrep عبارات باقاعده گسترش‌یافته را فعال می‌کند که شامل فراکاراکترهای اضافی برای تعویض (|) و گروه‌بندی (()) است.
  • استفاده از فلگ -P عبارات باقاعده سازگار با پرل (PCRE) را باز می‌کند که از قابلیت‌های پیشرفته‌ای مثل تطبیق تنبل (Lazy Matching) و Lookaround پشتیبانی می‌کنند.
  • ابزار zgrep دقیقاً مثل grep کار می‌کند اما برای جستجو در فایل‌های فشرده .gz بدون نیاز به باز کردن اولیه آن‌هاست.
  • در روندهای هوش مصنوعی و یادگیری ماشین، grep به‌عنوان ابزاری پرسرعت برای پاک‌سازی و پیش‌پردازش انبوه داده‌ها درخشش می‌کند.
  • grep برای مدیریت الگوهای چندخطی مناسب نیست؛ ابزارهای جایگزینی مثل awk و perl در این کار مؤثرترند.

پیش‌نیازها

برای دنبال کردن این راهنما به دسترسی به یک رایانه با سیستم‌عامل مبتنی بر لینوکس نیاز دارید. این می‌تواند یک سرور مجازی خصوصی باشد که با SSH به آن وصل شده‌اید یا ماشین محلی خودتان. توجه کنید که این آموزش روی یک سرور لینوکسی با اوبونتو 24.04 LTS اعتبارسنجی شده است، اما مثال‌های داده‌شده روی هر رایانه‌ای با هر نسخه‌ای از هر توزیع لینوکس باید کار کنند.

اگر قصد دارید از یک سرور ریموت برای دنبال کردن این راهنما استفاده کنید، پیشنهاد می‌کنیم ابتدا راهنمای راه‌اندازی اولیه سرور در پارمین کلود را کامل کنید. این کار یک محیط سروری امن برایتان آماده می‌کند—شامل کاربر غیر root با دسترسی sudo و فایروال پیکربندی‌شده با UFW—که می‌توانید با آن مهارت‌های لینوکسی‌تان را پرورش دهید.

استفاده پایه

در این آموزش از grep برای جستجوی کلمات و عبارات مختلف در فایل مجوز عمومی GNU نسخه ۳ (GNU General Public License version 3) استفاده می‌کنید.

اگر روی سیستم اوبونتویی هستید، فایل را در پوشه /usr/share/common-licenses پیدا می‌کنید. آن را به دایرکتوری خانه‌تان کپی کنید:

cp /usr/share/common-licenses/GPL-3 .

اگر روی سیستم دیگری هستید، با دستور curl یک نسخه دانلود کنید:

curl -o GPL-3 https://www.gnu.org/licenses/gpl-3.0.txt

در این آموزش از فایل مجوز BSD هم استفاده خواهید کرد. روی لینوکس می‌توانید آن را با این دستور به دایرکتوری خانه‌تان کپی کنید:

cp /usr/share/common-licenses/BSD .

اگر روی سیستم دیگری هستید، فایل را با این دستور بسازید:

cat << 'EOF' > BSD
Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
EOF

حالا که فایل‌ها را دارید، می‌توانید کار با grep را شروع کنید.

در ساده‌ترین شکل، از grep برای تطبیق الگوهای تحت‌اللفظی (Literal) داخل یک فایل متنی استفاده می‌کنید. یعنی اگر کلمه‌ای برای جستجو به grep بدهید، هر خطی از فایل که آن کلمه را دارد چاپ می‌کند.

این دستور را اجرا کنید تا grep هر خطی که کلمه GNU دارد را پیدا کند:

grep "GNU" GPL-3

آرگومان اول یعنی GNU الگویی است که دنبالش می‌گردید و آرگومان دوم یعنی GPL-3 فایل ورودی‌ای است که می‌خواهید جستجو کنید.

خروجی حاصل، هر خطی است که متن الگو را داشته باشد:

Output
                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
  Developers that use the GNU GPL protect your rights with two steps:
  "This License" refers to version 3 of the GNU General Public License.
  13. Use with the GNU Affero General Public License.
under version 3 of the GNU Affero General Public License into a single
...
...

روی برخی سیستم‌ها، الگویی که جستجو کرده‌اید در خروجی هایلایت می‌شود.

گزینه‌های رایج

به‌صورت پیش‌فرض، grep دقیقاً الگوی مشخص‌شده را در فایل ورودی جستجو می‌کند و خطوط پیدا شده را برمی‌گرداند. اما می‌توانید با افزودن چند فلگ اختیاری به grep، این رفتار را کاربردی‌تر کنید.

اگر می‌خواهید grep از بزرگی و کوچکی حروفِ پارامتر جستجو چشم‌پوشی کند و هم حالت‌های حروف بزرگ و هم کوچک را بگردد، گزینه -i یا --ignore-case را مشخص کنید.

هر نمونه از کلمه license (با حروف بزرگ، کوچک یا ترکیبی) را در همان فایل قبلی با این دستور جستجو کنید:

grep -i "license" GPL-3

نتایج شامل LICENSE، license و License است:

Output
                    GNU GENERAL PUBLIC LICENSE
 of this license document, but changing it is not allowed.
  The GNU General Public License is a free, copyleft license for
  The licenses for most software and other practical works are designed
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
(1) assert copyright on the software, and (2) offer you this License
  "This License" refers to version 3 of the GNU General Public License.
  "The Program" refers to any copyrightable work licensed under this
...
...

اگر نمونه‌ای با شکل LiCeNsE وجود داشت، آن هم برگردانده می‌شد.

اگر می‌خواهید همه خطوطی را که الگوی مشخص را ندارند پیدا کنید، از گزینه -v یا --invert-match استفاده کنید.

هر خطی که کلمه the را ندارد در مجوز BSD با این دستور جستجو کنید:

grep -v "the" BSD

این خروجی را دریافت می‌کنید:

Output
All rights reserved.

Redistribution and use in source and binary forms, with or without
are met:
    may be used to endorse or promote products derived from this software
    without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

چون گزینه «بی‌توجهی به بزرگی و کوچکی حروف» را مشخص نکردید، دو مورد آخر به‌عنوان خطوطی که کلمه the را ندارند برگردانده شدند.

اغلب دانستن شماره خطی که تطبیق‌ها روی آن رخ داده‌اند مفید است. این کار را با گزینه -n یا --line-number انجام دهید. مثال قبلی را با افزودن این فلگ دوباره اجرا کنید:

grep -vn "the" BSD

این متن برگردانده می‌شود:

Output
2:All rights reserved.
3:
4:Redistribution and use in source and binary forms, with or without
6:are met:
13:   may be used to endorse or promote products derived from this software
14:   without specific prior written permission.
15:
16:THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17:ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
...
...

حالا اگر بخواهید روی هر خطی که the ندارد تغییری بدهید، می‌توانید به شماره خط ارجاع بدهید. این به‌ویژه وقتی با سورس‌کد کار می‌کنید خیلی به کار می‌آید.

عبارات باقاعده

در مقدمه یاد گرفتید که grep مخفف «global regular expression print» است. «عبارت باقاعده» (Regular Expression) یک رشته متنی است که یک الگوی جستجوی خاص را توصیف می‌کند.

اپلیکیشن‌ها و زبان‌های برنامه‌نویسی مختلف عبارات باقاعده را کمی متفاوت پیاده‌سازی می‌کنند. در این آموزش فقط زیرمجموعه کوچکی از نحوه توصیف الگوها توسط grep را بررسی می‌کنید.

تطبیق‌های تحت‌اللفظی

در مثال‌های قبلی این آموزش، وقتی دنبال کلمات GNU و the می‌گشتید، در واقع در حال جستجوی عبارات باقاعده پایه‌ای بودید که دقیقاً با رشته کاراکترهای GNU و the تطبیق می‌یافتند. الگوهایی که دقیقاً کاراکترهای مورد تطبیق را مشخص می‌کنند «تحت‌اللفظی» (Literal) نامیده می‌شوند؛ چون الگو را تحت‌اللفظی، کاراکتر به کاراکتر تطبیق می‌دهند.

مفید است که این‌ها را به‌عنوان تطبیق با یک رشته کاراکتری در نظر بگیرید، نه تطبیق با یک کلمه. وقتی الگوهای پیچیده‌تری را یاد می‌گیرید، این تمایز اهمیت بیشتری پیدا می‌کند.

همه کاراکترهای الفبایی و عددی (و همچنین برخی کاراکترهای دیگر) به‌صورت تحت‌اللفظی تطبیق می‌یابند، مگر اینکه توسط سازوکارهای دیگر عبارت تغییر داده شوند.

تطبیق‌های لنگری (Anchor)

لنگرها کاراکترهای خاصی هستند که مشخص می‌کنند تطبیق باید در کجای خط رخ بدهد تا معتبر باشد.

مثلاً با استفاده از لنگرها می‌توانید مشخص کنید که فقط خطوطی را می‌خواهید که GNU در ابتدای خط با آن مطابقت دارد. برای این کار، لنگر ^ را قبل از رشته تحت‌اللفظی قرار دهید.

این دستور را اجرا کنید تا فایل GPL-3 را جستجو کنید و خطوطی را ببینید که GNU در ابتدای خط آمده است:

grep "^GNU" GPL-3

این دستور این دو خط را برمی‌گرداند:

Output
GNU General Public License for most of our software; it applies also to
GNU General Public License, you may choose any version ever published

به‌طور مشابه، لنگر $ را در انتهای الگو استفاده می‌کنید تا نشان دهید تطبیق فقط وقتی معتبر است که در انتهای خط رخ دهد.

این دستور با هر خطی که به کلمه and ختم می‌شود در فایل GPL-3 مطابقت می‌یابد:

grep "and$" GPL-3

این خروجی را دریافت می‌کنید:

Output
that there is no warranty for this free software.  For both users' and
  The precise terms and conditions for copying, distribution and
  License.  Each licensee is addressed as "you".  "Licensees" and
receive it, in any medium, provided that you conspicuously and
    alternative is allowed only occasionally and noncommercially, and
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
provisionally, unless and until the copyright holder explicitly and
receives a license from the original licensors, to run, modify and
make, use, sell, offer for sale, import and otherwise run, modify and

تطبیق با هر کاراکتر

کاراکتر نقطه (.) در عبارات باقاعده به این معناست که هر کاراکتر منفردی می‌تواند در موقعیت مشخص‌شده وجود داشته باشد.

مثلاً برای تطبیق هر چیزی در فایل GPL-3 که دو کاراکتر و بعد رشته cept دارد، از این الگو استفاده می‌کنید:

grep "..cept" GPL-3

این دستور این خروجی را برمی‌گرداند:

Output
use, which is precisely where it is most unacceptable.  Therefore, we
infringement under applicable copyright law, except executing it on a
tells the user that there is no warranty for the work (except to the
License by making exceptions from one or more of its conditions.
form of a separately written license, or stated as exceptions;
  You may not propagate or modify a covered work except as expressly
  9. Acceptance Not Required for Having Copies.
...
...

این خروجی شامل نمونه‌هایی از هر دو کلمه accept و except و تنوع‌هایی از این دو کلمه است. اگر z2cept وجود داشت، الگو با آن هم تطبیق می‌یافت.

عبارات براکتی

با قرار دادن گروهی از کاراکترها داخل براکت ([ و ])، می‌توانید مشخص کنید که کاراکترِ آن موقعیت می‌تواند هر یک از کاراکترهای موجود در گروه براکت باشد.

مثلاً برای پیدا کردن خطوطی که too یا two دارند، این تنوع‌ها را به‌طور فشرده با این الگو مشخص کنید:

grep "t[wo]o" GPL-3

خروجی نشان می‌دهد هر دو تنوع در فایل وجود دارند:

Output
your programs, too.
freedoms that you received.  You must make sure that they, too, receive
  Developers that use the GNU GPL protect your rights with two steps:
a computer network, with no transfer of a copy, is not conveying.
System Libraries, or general-purpose tools or generally available free
    Corresponding Source from a network server at no charge.
...
...

نوشتار براکتی گزینه‌های جالبی به شما می‌دهد. می‌توانید کاری کنید الگو با هر چیزی به‌جز کاراکترهای داخل براکت تطبیق یابد؛ کافی است فهرست کاراکترهای داخل براکت را با کاراکتر ^ شروع کنید.

این مثال شبیه الگوی .ode است، اما با الگوی code تطبیق نمی‌یابد:

grep "[^c]ode" GPL-3

این خروجی را دریافت می‌کنید:

Output
  1. Source Code.
    model, to give anyone who possesses the object code either (1) a
the only significant mode of use of the product.
notice like this when it starts in an interactive mode:

دقت کنید که در خط دوم برگردانده‌شده، در واقع کلمه code وجود دارد. این شکستِ عبارت باقاعده یا grep نیست؛ بلکه این خط به این دلیل برگردانده شد که الگوی mode که داخل کلمه model وجود دارد، جلوتر در همان خط پیدا شد. خط برگردانده شد چون نمونه‌ای وجود داشت که با الگو مطابقت داشت.

قابلیت مفید دیگر براکت‌ها این است که می‌توانید به‌جای تایپ تک‌تک همه کاراکترها، یک بازه از کاراکترها را مشخص کنید.

یعنی اگر می‌خواهید هر خطی که با حرف بزرگ شروع می‌شود را پیدا کنید، از این الگو استفاده کنید:

grep "^[A-Z]" GPL-3

این خروجیِ این عبارت است:

Output
GNU General Public License for most of our software; it applies also to
States should not allow patents to restrict development and use of
License.  Each licensee is addressed as "you".  "Licensees" and
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
System Libraries, or general-purpose tools or generally available free
Source.
User Product is transferred to the recipient in perpetuity or for a
...
...

به‌دلیل برخی مشکلات مرتب‌سازی قدیمی، اغلب استفاده از کلاس‌های کاراکتری POSIX دقیق‌تر از بازه‌های کاراکتری است.

بحث درباره همه کلاس‌های کاراکتری POSIX فراتر از محدوده این راهنماست، اما مثالی که همان کار مثال قبلی را انجام می‌دهد، از کلاس کاراکتری [:upper:] داخل سلکتور براکت استفاده می‌کند:

grep "^[[:upper:]]" GPL-3

خروجی مثل قبل خواهد بود.

تکرار الگو صفر بار یا بیشتر

در نهایت، یکی از پرکاربردترین فراکاراکترها، ستاره یا * است که یعنی «کاراکتر یا عبارت قبلی را صفر بار یا بیشتر تکرار کن».

برای پیدا کردن هر خطی در فایل GPL-3 که پرانتز باز و بسته دارد و فقط حروف و فاصله‌های منفرد بین آن‌هاست، از این عبارت استفاده کنید:

grep "([A-Za-z ]*)" GPL-3

این خروجی را می‌گیرید:

Output
 Copyright (C) 2007 Free Software Foundation, Inc.
distribution (with or without modification), making available to the
than the work as a whole, that (a) is included in the normal form of
Component, and (b) serves only to enable use of the work with that
(if any) on which the executable work runs, or a compiler used to
    (including a physical distribution medium), accompanied by the
    (including a physical distribution medium), accompanied by a
    place (gratis or for a charge), and offer equivalent access to the
...
...

تا اینجا در عبارت‌هایتان از نقطه، ستاره و کاراکترهای دیگر استفاده کردید؛ اما گاهی لازم است خود آن کاراکترها را جستجو کنید.

فراکاراکترها را Escape کنید

گاهی لازم است یک نقطه تحت‌اللفظی یا براکت باز تحت‌اللفظی را جستجو کنید؛ به‌ویژه وقتی با سورس‌کد یا فایل‌های پیکربندی کار می‌کنید. چون این کاراکترها در عبارات باقاعده معنای خاصی دارند، باید آن‌ها را «escape» کنید تا به grep بگویید که در این مورد نمی‌خواهید از معنای خاصشان استفاده کنید.

Escape کردن کاراکترها با قرار دادن کاراکتر بک‌اسلش (\) قبل از کاراکتری که معمولاً معنای خاصی دارد انجام می‌شود.

مثلاً برای پیدا کردن هر خطی که با حرف بزرگ شروع می‌شود و به نقطه ختم می‌شود، از این عبارت استفاده کنید که نقطه پایانی را escape می‌کند تا نقطه تحت‌اللفظی را نشان بدهد، نه معنای همیشگی‌اش یعنی «هر کاراکتری»:

grep "^[A-Z].*\.$" GPL-3

این خروجی را می‌بینید:

Output
Source.
License by making exceptions from one or more of its conditions.
License would be to refrain entirely from conveying the Program.
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
SUCH DAMAGES.
Also add information on how to contact you by electronic and paper mail.

حالا به گزینه‌های دیگر عبارات باقاعده نگاه کنیم.

عبارات باقاعده گسترش‌یافته

دستور grep با استفاده از فلگ -E یا فراخوانی دستور egrep به‌جای grep، از یک زبان عبارت باقاعده گسترده‌تر پشتیبانی می‌کند.

این گزینه‌ها قابلیت‌های «عبارات باقاعده گسترش‌یافته» (Extended Regular Expressions) را باز می‌کنند. عبارات گسترش‌یافته شامل همه فراکاراکترهای پایه به‌همراه فراکاراکترهای اضافی برای بیان تطبیق‌های پیچیده‌تر هستند.

گروه‌بندی

یکی از مفیدترین توانایی‌هایی که عبارات گسترش‌یافته فراهم می‌کنند، امکان گروه‌بندی عبارات برای دستکاری یا ارجاع به‌عنوان یک واحد است.

برای گروه‌بندی عبارات، آن‌ها را داخل پرانتز قرار دهید. اگر می‌خواهید بدون استفاده از عبارات گسترش‌یافته از پرانتز استفاده کنید، می‌توانید با بک‌اسلش آن‌ها را escape کنید تا این قابلیت فعال شود. یعنی این سه عبارت از نظر عملکردی معادل‌اند:

grep "\(grouping\)" file.txt
grep -E "(grouping)" file.txt
egrep "(grouping)" file.txt

تعویض (Alternation)

مشابه اینکه عبارات براکتی می‌توانند انتخاب‌های مختلف ممکن برای تطبیق کاراکتر منفرد را مشخص کنند، تعویض به شما اجازه می‌دهد تطبیق‌های جایگزین برای رشته‌ها یا مجموعه‌های عبارت مشخص کنید.

برای نشان دادن تعویض، از کاراکتر پایپ | استفاده کنید. این‌ها اغلب داخل گروه‌بندی پرانتزی استفاده می‌شوند تا مشخص کنند یکی از دو یا چند احتمال باید به‌عنوان تطبیق در نظر گرفته شود.

عبارت زیر یا GPL یا General Public License را در متن پیدا می‌کند:

grep -E "(GPL|General Public License)" GPL-3

خروجی به این شکل است:

Output
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
price.  Our General Public Licenses are designed to make sure that you
  Developers that use the GNU GPL protect your rights with two steps:
  For the developers' and authors' protection, the GPL clearly explains
authors' sake, the GPL requires that modified versions be marked as
have designed this version of the GPL to prohibit the practice for those
...
...

تعویض می‌تواند بین بیش از دو گزینه انتخاب کند؛ کافی است گزینه‌های اضافی را با کاراکترهای پایپ (|) بیشتر داخل گروه انتخاب جدا کنید.

کمّیت‌دهنده‌ها (Quantifiers)

مانند فراکاراکتر * که کاراکتر یا مجموعه کاراکتر قبلی را صفر بار یا بیشتر تطبیق می‌داد، فراکاراکترهای دیگری هم در عبارات گسترش‌یافته موجودند که تعداد تکرار را مشخص می‌کنند.

برای تطبیق یک کاراکتر صفر یا یک بار، می‌توانید از کاراکتر ? استفاده کنید. این کاراکتر یا مجموعه‌های کاراکتری قبل از خود را در اصل اختیاری می‌کند.

عبارت زیر با قرار دادن copy در یک گروه اختیاری، هم copyright و هم right را تطبیق می‌دهد:

grep -E "(copy)?right" GPL-3

این خروجی را دریافت می‌کنید:

Output
 Copyright (C) 2007 Free Software Foundation, Inc.
  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
know their rights.
  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
  "Copyright" also means copyright-like laws that apply to other kinds of
...

کاراکتر + یک عبارت را یک بار یا بیشتر تطبیق می‌دهد. این تقریباً شبیه فراکاراکتر * است، اما با کاراکتر +، عبارت باید حداقل یک بار مطابقت داشته باشد.

عبارت زیر رشته free به‌همراه یک یا چند کاراکتر که کاراکتر فاصله سفید نیستند را تطبیق می‌دهد:

grep -E "free[^[:space:]]+" GPL-3

این خروجی را می‌بینید:

Output
  The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
  When we speak of free software, we are referring to freedom, not
have the freedom to distribute copies of free software (and charge for
you modify it: responsibilities to respect the freedom of others.
freedoms that you received.  You must make sure that they, too, receive
protecting users' freedom to change the software.  The systematic
of the GPL, as needed to protect the freedom of users.
patents cannot be used to render the program non-free.

مشخص کردن تکرار تطبیق

برای مشخص کردن تعداد تکرار یک تطبیق، از کاراکترهای آکولاد ({ و }) استفاده کنید. این کاراکترها به شما اجازه می‌دهند تعداد دقیق، یک بازه، یا حد بالایی یا پایینی برای تعداد دفعاتی که یک عبارت می‌تواند مطابقت یابد مشخص کنید.

از این عبارت برای پیدا کردن همه خطوطی در فایل GPL-3 که سه‌گانه مصوت دارند استفاده کنید:

grep -E "[AEIOUaeiou]{3}" GPL-3

هر خط برگردانده‌شده کلمه‌ای با سه مصوت دارد:

Output
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
receive it, in any medium, provided that you conspicuously and
give under the previous paragraph, plus a right to possession of the
covered work so as to satisfy simultaneously your obligations under this

برای تطبیق هر کلمه‌ای که بین ۱۶ تا ۲۰ کاراکتر دارد، از این عبارت استفاده کنید:

grep -E "[[:alpha:]]{16,20}" GPL-3

خروجی این دستور این است:

Output
    certain responsibilities if you distribute copies of the software, or if
    you modify it: responsibilities to respect the freedom of others.
        c) Prohibiting misrepresentation of the origin of that material, or

فقط خطوطی که کلماتی با آن طول دارند نمایش داده می‌شوند.

تطبیق الگوی پیشرفته با PCRE (grep -P)

در حالی که عبارات باقاعده گسترش‌یافته (-E) قدرت زیادی اضافه می‌کنند، برخی سیستم‌ها موتور پرامکانات‌تری هم ارائه می‌دهند: عبارات باقاعده سازگار با پرل (PCRE). این قابلیت را با فلگ -P باز می‌کنید. این موتور در زبان‌های برنامه‌نویسی مثل پایتون و جاوااسکریپت رایج است و قابلیت‌های پیشرفته را مستقیماً به خط فرمان شما می‌آورد.

نکته: گزینه -P یک توسعه GNU است و ممکن است روی همه سیستم‌ها موجود نباشد؛ مثلاً روی نسخه پیش‌فرض grep در مک (که مبتنی بر BSD است) در دسترس نیست.

دو قابلیت قدرتمند PCRE را بررسی کنیم: تطبیق تنبل (Lazy Matching) و Lookaround.

تطبیق حریصانه در مقابل تنبل

به‌طور پیش‌فرض، کمّیت‌دهنده‌هایی مثل * و + حریص‌اند. یعنی سعی می‌کنند بلندترین رشته ممکن را تطبیق دهند. مثلاً اگر متن <a>test1</a> <a>test2</a> را دارید و سعی کنید یک تگ HTML را با <.*> تطبیق دهید، الگو کل رشته را از اولین < تا آخرین > تطبیق می‌دهد.

فایلی به نام tags.html بسازید تا این را در عمل ببینید:

echo '<a>test1</a> <a>test2</a>' > tags.html

حالا یک جستجوی حریصانه اجرا کنید:

grep -P -o "<.*>" tags.html

فلگ -o به grep می‌گوید فقط بخش تطبیق‌یافته خط را خروجی بدهد. نتیجه کل خط است که اغلب چیزی نیست که بخواهید:

Output
<a>test1</a> <a>test2</a>

برای حل این مشکل، می‌توانید کمّیت‌دهنده را تنبل کنید؛ با اضافه کردن ? بعد از آن. کمّیت‌دهنده تنبل کوتاه‌ترین رشته ممکن را تطبیق می‌دهد:

grep -P -o "<.*?>" tags.html

این درست هر تگ را به‌عنوان یک تطبیق جداگانه شناسایی می‌کند:

Output
<a>
</a>
<a>
</a>

تطبیق تنبل وقتی ضروری است که متنی با جداکننده‌های شروع و پایان مشخص اما محتوای متغیر بین آن‌ها را پارس می‌کنید.

Lookaround

مکانیزم‌های Lookaround ادعاهای بدون عرض (Zero-Width) هستند. به شما اجازه می‌دهند وجود یک الگو را قبل (Lookbehind) یا بعد (Lookahead) از الگوی اصلی‌تان بررسی کنید بدون اینکه آن را در تطبیق واقعی بگنجانید. این برای تطبیق بر اساس زمینه (Context) فوق‌العاده مفید است.

  • Lookahead مثبت ((?=...)): ادعا می‌کند که زیرالگوی ... باید بعد از الگوی اصلی بیاید.
  • Lookbehind مثبت ((?<=...)): ادعا می‌کند که زیرالگوی ... باید قبل از الگوی اصلی آمده باشد.

فرض کنید می‌خواهید هر نمونه از کلمه «license» را در GPL-3 پیدا کنید، اما فقط وقتی بلافاصله کلمه «document» بعدش آمده است:

grep -P -o "license(?= document)" GPL-3

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

Output
license

به‌طور مشابه می‌توانید از Lookbehind مثبت برای پیدا کردن عددی که رشته “version ” قبلش آمده استفاده کنید:

grep -P -o "(?<=version )[0-9]" GPL-3

این دستور شماره نسخه 3 را از عبارت «version 3» پیدا می‌کند بدون اینکه “version ” را در خروجی بگنجاند:

Output
3
3
3

مکانیزم‌های Lookaround ابزاری قدرتمند برای استخراج اطلاعات دقیق از متن ساختاریافته هستند.

کارایی، قابلیت انتقال و اسکریپت‌نویسی پیشرفته

وقتی با عملکردهای اصلی grep راحت شدید، می‌توانید روی سریع‌تر کردن جستجوها، قابل اطمینان‌تر کردن اسکریپت‌ها و کارآمدتر کردن روند کاری‌تان تمرکز کنید.

کارایی و بهینه‌سازی

همه عبارات باقاعده یکسان ساخته نمی‌شوند. یک الگوی بدنویسی‌شده می‌تواند به‌طور چشمگیری از یک الگوی کارآمد کندتر باشد؛ به‌ویژه روی فایل‌های بزرگ.

کارایی Regex: از الگوهای پیچیده با کمّیت‌دهنده‌های تودرتو و تعویض مانند (a|b*)+ احتیاط کنید. این‌ها می‌توانند به شرایطی به نام backtracking فاجعه‌بار منجر شوند که زمان اجرای موتور regex به‌صورت نمایی رشد می‌کند. تا جای ممکن، الگوهایی مشخص‌تر بنویسید و از ابهام بپرهیزید.

جایگزین‌های مدرن: برای جستجو در کدبیس‌های بزرگ، ابزارهایی مثل ripgrep (rg) برای سرعت ساخته شده‌اند. آن‌ها اغلب با بهره‌گیری از موازی‌سازی (Parallelism) و پیش‌فرض‌های هوشمند—مثل نادیده گرفتن خودکار فایل‌های فهرست‌شده در .gitignore—بهتر از grep عمل می‌کنند.

فلگ‌های کارآمد مفید:

  • --line-buffered: وقتی grep بخشی از یک پایپ‌لاین است (مثلاً tail -f logfile | grep 'ERROR')، این فلگ آن را مجبور می‌کند خروجی را خط به خط پردازش کند. این برای مانیتورینگ بلادرنگ لاگ‌ها حیاتی است و تضمین می‌کند تطبیق‌ها را هم‌زمان با رخ دادنشان ببینید، نه اینکه منتظر پر شدن بافر خروجی بمانید.
  • --mmap: روی برخی سیستم‌ها، این گزینه می‌تواند با استفاده از I/O نگاشت‌شده در حافظه برای خواندن فایل‌ها کارایی را بهبود دهد؛ که برای فایل‌های بسیار بزرگ می‌تواند از عملیات خواندن استاندارد سریع‌تر باشد.

قابلیت انتقال و تنوع‌های grep

یک شل اسکریپت که روی ماشین لینوکسی شما کار می‌کند، ممکن است روی مکِ همکارتان شکست بخورد. این اغلب به تفاوت‌های بین GNU grep (استاندارد روی لینوکس) و BSD grep (استاندارد روی macOS) برمی‌گردد. GNU grep عموماً امکانات بیشتری دارد؛ مثل موتور PCRE (-P) و گزینه‌های پیشرفته‌تر. اگر قابلیت انتقال (Portability) هدفتان است، همیشه اسکریپت‌هایتان را در محیط‌های مختلف تست کنید.

برای یک کار رایج مدیر سیستمی—مثل جستجو در فایل‌های لاگ فشرده—لازم نیست اول آن‌ها را باز کنید. ابزار zgrep دقیقاً مثل grep کار می‌کند اما روی فایل‌های فشرده .gz:

zgrep "ERROR" /var/log/syslog.2.gz

این دستور عبارت «ERROR» را داخل فایل فشرده syslog.2.gz جستجو می‌کند بدون ساخت یک فایل موقتِ باز شده.

تکنیک‌های اسکریپت‌نویسی پیشرفته

هنگام ساخت اسکریپت‌ها، مقاوم‌بودن (Robustness) کلیدی است. نام فایل‌هایی با فاصله یا کاراکترهای خاص می‌توانند پایپ‌لاین‌های ساده را بشکنند.

پایپ‌لاین‌های امن با --null: دستور grep -l فایل‌های دارای تطبیق را فهرست می‌کند. اگر این فهرست را به دستور دیگری مثل xargs پایپ کنید، نام فایل‌هایی که فاصله دارند خطا ایجاد می‌کنند. برای حل این مشکل، از گزینه -Z یا --null استفاده کنید که نام فایل‌ها را با کاراکتر null به‌جای خط جدید جدا می‌کند. دستور xargs بعد می‌تواند این ورودی را با گزینه -0 بخواند:

grep -lZ "pattern" /path/* | xargs -0 rm

این دستور به‌شکل امن همه فایل‌های /path/ را که «pattern» دارند پیدا و حذف می‌کند؛ حتی اگر نام‌شان شامل فاصله یا کاراکترهای خاص باشد.

ورودی توصیفی با --label: وقتی ورودی را از دستور دیگری به grep پایپ می‌کنید، منبع معمولاً با برچسب (standard input) مشخص می‌شود. فلگ --label به شما اجازه می‌دهد نام توصیفی‌تری اختصاص دهید که برای ساخت لاگ‌ها یا خروجی اسکریپت‌های شفاف‌تر مفید است:

echo "This is an error" | grep --label="ErrorStream" "error"

خروجی:

Output
ErrorStream: This is an error

موارد استفاده عملی

۱. اعتبارسنجی فیلدهای CSV

برای اعتبارسنجی فیلدهای CSV می‌توانید از grep با عبارات باقاعده برای بررسی الگوها یا فرمت‌های خاص استفاده کنید. مثلاً برای بررسی اینکه آیا همه خطوط یک فایل CSV دقیقاً ۵ فیلد جدا شده با ویرگول دارند، از این دستور استفاده کنید:

grep -E "^[^,]+,[^,]+,[^,]+,[^,]+,[^,]+$" yourfile.csv

این دستور فقط خطوطی را چاپ می‌کند که با الگوی مشخص‌شده مطابقت دارند و نشان می‌دهد فیلدهای CSV معتبرند.

۲. فیلتر کردن لاگ‌ها بر اساس سطح خطا

فیلتر کردن لاگ‌ها بر اساس سطح خطا یک مورد استفاده رایج برای grep است. برای فیلتر خطوطی که کلمه «ERROR» دارند، از این دستور استفاده کنید:

grep "ERROR" logs.txt

این دستور همه خطوط logs.txt که کلمه «ERROR» را دارند چاپ می‌کند تا روی پیام‌های خطا تمرکز کنید.

۳. جستجو در سورس‌کد برای توابع خاص

هنگام جستجو در سورس‌کد، grep را می‌توان برای پیدا کردن توابع یا الگوهای خاص استفاده کرد. مثلاً برای پیدا کردن همه نمونه‌های تابعی به نام calculateTotal در یک دایرکتوری از فایل‌های سورس‌کد، از این دستور استفاده کنید:

grep -r "calculateTotal" /path/to/source/code/directory

این دستور همه فایل‌های دایرکتوری مشخص‌شده را به‌صورت بازگشتی جستجو می‌کند و خطوطی را که نام تابع دارند چاپ می‌کند.

۴. تطبیق URLها یا آدرس‌های ایمیل در متن

عبارات باقاعده را می‌توان برای تطبیق URLها یا آدرس‌های ایمیل در متن استفاده کرد. مثلاً برای پیدا کردن همه خطوطی که URL دارند، از این دستور استفاده کنید:

grep -E "https?://[^ ]+" yourfile.txt

این دستور همه خطوطی را چاپ می‌کند که URLای با شروع «http://» یا «https://» دارند.

۵. پیش‌پردازش NLP: حذف خطوط دارای کلمات ایستا (Stopword)

کلمات ایستا کلمات رایجی مثل «the» و «and» هستند که معنای زیادی در جمله ندارند. برای فیلتر کردن خطوطی که کلمات ایستا دارند، از grep با فهرستی از کلمات ایستا استفاده کنید. مثلاً برای حذف خطوطی که کلمات ایستای «the»، «and» یا «a» دارند:

grep -vE "the|and|a" yourfile.txt

این دستور همه خطوطی را چاپ می‌کند که هیچ‌کدام از کلمات ایستای مشخص‌شده را ندارند.

۶. تشخیص ورودی‌های تکراری‌نزدیک یا غلط‌های املایی

عبارات باقاعده را می‌توان برای تشخیص ورودی‌های تکراری‌نزدیک یا غلط‌های املایی با تطبیق الگوهای مشابه استفاده کرد. مثلاً برای پیدا کردن خطوطی که کلماتی با تفاوت یک کاراکتری دارند:

grep -E "(\w)\1" yourfile.txt

این دستور همه خطوطی را چاپ می‌کند که کلماتی با تکرار یک کاراکتر دارند؛ که نشانه‌ای از تکراری‌های نزدیک یا غلط‌های املایی بالقوه است.

۷. الگوهای Regex برای موجودیت‌های نامی یا عبارات رایج

عبارات باقاعده را می‌توان برای تطبیق موجودیت‌های نامی (Named Entity) یا عبارات رایج در متن استفاده کرد. مثلاً برای پیدا کردن همه خطوطی که عبارت خاصی مثل «named entity recognition» دارند:

grep -E "named entity recognition" yourfile.txt

این دستور همه خطوطی را چاپ می‌کند که عبارت مشخص‌شده را دارند تا روی اطلاعات مرتبط تمرکز کنید.

۸. DevOps: فیلتر کردن لاگ‌های CI/CD

پایپ‌لاین‌های یکپارچه‌سازی و دیپلوی پیوسته می‌توانند هزاران خط خروجی لاگ تولید کنند. grep برای پیدا کردن سریع منشأ خرابی不可缺少 (ضروری) است. می‌توانید دستورات grep را با -v زنجیر کنید تا نویزهای معمول را حذف و روی خطاهای حیاتی تمرکز کنید.

لاگ بیلدی پرجزئیات به نام build.log را تصور کنید. می‌خواهید پیام‌های خطا را پیدا کنید اما هشدارهای رایج درباره deprecation را حذف کنید:

grep "ERROR" build.log | grep -v "DEPRECATED"

این پایپ‌لاین ابتدا همه خطوط حاوی «ERROR» را انتخاب می‌کند و بعد هر کدام از آن خطوط را که «DEPRECATED» هم دارند فیلتر می‌کند؛ تا روی خرابی‌های قابل اقدام متمرکز شوید.

۹. مدیریت سیستم: جستجو در لاگ‌های سیستم

مدیران سیستم اغلب از grep برای پارس لاگ‌های تولیدشده توسط سرویس‌ها استفاده می‌کنند. روی سیستم‌های مدرن لینوکس که از systemd استفاده می‌کنند، لاگ‌ها توسط journalctl مدیریت می‌شوند. می‌توانید خروجی‌اش را به grep پایپ کنید تا سریع مشکلات سرویس را تشخیص دهید.

برای پیدا کردن همه ورودی‌های لاگ وب‌سرور NGINX که کلمه «failed» را دارند (بدون حساسیت به بزرگی و کوچکی حروف):

journalctl -u nginx.service | grep -i "failed"

این دستور تک‌خطی اغلب اولین قدم در عیب‌یابی یک سرویس سیستمی خراب است.

۱۰. امنیت: اسکن برای اسرار افشاشده

یک اشتباه امنیتی رایج، کامیت کردن اعتبارنامه‌ها یا کلیدهای API در مخزن کد است. grep می‌تواند یک اسکن سریع و بازگشتی از یک دایرکتوری برای پیدا کردن این اسرار انجام دهد.

برای جستجوی بازگشتی (-r) در دایرکتوری فعلی برای الگوهای رایجی مثل API_KEY، با بی‌توجهی به بزرگی و کوچکی حروف (-i):

grep -r -i "API_KEY" .

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

grep در عصر هوش مصنوعی

grep که دستوری کلاسیک و ساخته دهه ۱۹۷۰ است، در عصر مدرن هوش مصنوعی (AI) هيچ‌چیز از اعتبارش را از دست نداده است. نقش آن از یک ابزار جستجوی ساده به جزء حیاتی در اکوسیستم پیچیده ابزارهای توسعه‌دهنده تکامل یافته است. امروز grep به‌عنوان ابزار بنیادی پرسرعتی برای دستکاری داده و مکملی کامل برای قدرت شناختی هوش مصنوعی عمل می‌کند. این بخش رابطه پویا بین grep و AI را بررسی می‌کند و نشان می‌دهد که این دستور چند دهه‌ای چگونه هم فناوری پیشرفته را تقویت می‌کند و هم توسط آن تقویت می‌شود.

مدیریت عبارات باقاعده با کمک AI

تسلط بر سینتکس عبارات باقاعده همیشه مانعی بزرگ برای توسعه‌دهنده‌ها بوده است. الگوهای پیچیده به‌طور بدنامی برای نوشتن سخت و برای رمزگشایی سخت‌ترند. دستیارهای هوش مصنوعی مدرن مانند پلی قدرتمند عمل می‌کنند و قدرت کامل regex را برای همه قابل دسترس می‌کنند.

تولید Regex با AI: تصور کنید لازم است یک نام کاربری را بر اساس مجموعه‌ای از قوانین پیچیده اعتبارسنجی کنید: باید ۸ تا ۱۶ کاراکتر باشد، با حرف شروع شود، حداقل یک عدد داشته باشد و زیرخط را بپذیرد اما نه در ابتدا یا انتها. ساختن این regex با دست، فرایندی دقيق و مستعد خطاست. با دستیار هوش مصنوعی مثل GitHub Copilot یا ChatGPT می‌توانید این الزامات را به زبان ساده توصیف کنید. AI نیت شما را به یک الگوی دقیق و کارING (کارا) تبدیل می‌کند و اغلب نسخه‌ای سازگار با گونه خاص regex در grep ارائه می‌دهد. این کار را از یک پازل خسته‌کننده به یک تبادل ساده گفت‌وگومحور تبدیل می‌کند.

AI برای توضیح‌پذیری Regex: رایج‌تر از آن، به ارث رساندن اسکریپتی است که regexای رمزآلود مثل ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$ دارد. در یک نگاه، این تقریباً ناخواناست. به‌جای صرف یک ساعت برای رمزگشایی دقیق آن، می‌توانید آن را در ابزار AI قرار دهید و توضیح بخواهید. AI مانند مترجمی عمل می‌کند و آن را تکه‌تکه تجزیه می‌کند: «(?=.*[a-z]) یک Lookahead مثبت است که وجود حداقل یک حرف کوچک را تضمین می‌کند…» این قابلیت برای دیباگ، بازآفرینی کدهای قدیمی (Legacy) و شتاب دادن به فرایند یادگیری توسعه‌دهنده‌های تازه‌کار بی‌قیمت است.

نقش grep در هوش مصنوعی و یادگیری ماشین

در حوزه AI و یادگیری ماشین (ML)، داده ماده خام است و کیفیت آن موفقیت مدل نهایی را تعیین می‌کند. قبل از اینکه الگوریتم‌های پیچیده اصلاً بتوانند کارشان را شروع کنند، دیتاست‌های عظیم باید فیلتر، پاک‌سازی و ساختاردهی شوند. در این مرحله حیاتی پیش‌پردازش، grep به‌عنوان ابزاری قدرتمند و پرسرعت برای پاک‌سازی انبوه داده درخشش می‌کند.

پیش‌پردازش و پاک‌سازی داده: چالش آماده‌سازی یک دیتاست متنی عظیم ۵۰ گیگابایتی برای آموزش یک مدل زبانی طبیعی را در نظر بگیرید. این داده خام که از وب جمع‌آوری شده، به‌ناگزیر کثیف است. ممکن است شامل تگ‌های باقی‌مانده HTML، قطعات JSON ناقص یا خطوطی با کاراکترهای غیر UTF-8 باشد. اجرای یک اسکریپت ظریف پایتون روی این فایل خام ناکارآمد و پرریسک است—یک خط بد می‌تواند کل فرایند را زمین بزند.

grep یک خط دفاعی اولِ مقاوم و تحمل‌پذیرِ خطا فراهم می‌کند. می‌توانید از آن در یک پایپ‌لاین برای انجام وظایف پاک‌سازی حیاتی با سرعت شگفت‌انگیز استفاده کنید:

  • ایزوله کردن داده مرتبط: grep '"text":' فقط خطوطی را استخراج می‌کند که فیلد داده موردنظر را دارند.
  • حذف خطوط خراب: grep -v "<!DOCTYPE html>" سریعاً هر سند HTML آلوده را حذف می‌کند.
  • فیلتر بر اساس معیار: grep -E "\b(error|failed|exception)\b" می‌تواند یک دیتاست کوچک‌تر و متمرکز از متن‌های مرتبط با خطا برای آموزش مدل تخصصی بسازد.

با استفاده از grep برای این فیلترینگ اولیه با حجم بالا، منابع محاسباتی ارزشمند را حفظ می‌کنید و مطمئن می‌شوید ابزارهای بعدی AI/ML دیتاستی تمیز و خوش‌ساخت دریافت می‌کنند تا کارآمدتر و مؤثرتر عمل کنند.

مقایسه زمینه‌ای: grep در مقابل ابزارهای مدرن AI

برای فهم جایگاه grep در جعبه‌ابزار مدرن، بهترین راه نگاه از منظر بده‌وبستان‌هاست. grep مانند یک تیغ جراحی فوق تیز است: یک کار مشخص—تطبیق متن—را با سرعت و دقتی بی‌رقیب انجام می‌دهد. ابزارهای قدرت‌گرفته از AI کندترند اما درک عمیق و زمینه‌ای از کل سیستم ارائه می‌دهند.

جدول زیر مقایسه تفصیلی‌تری ارائه می‌کند:

ویژگیgrepابزارهای AI (مثل Sourcegraph و Copilot)
روش جستجوتطبیق متنی تحت‌اللفظی و مبتنی بر الگو. دنبال توالی کاراکترها می‌گردد.جستجوی معنایی، زمینه‌ای و مفهومی. معنا و روابط را پیدا می‌کند.
آگاهیخط‌محور. هیچ درکی از سینتکس کد، محدوده (Scope) یا ساختار ندارد.آگاه از کد. توابع، کلاس‌ها، محدوده متغیرها و وابستگی‌ها را می‌فهمد.
پرسش اصلی«آیا این رشته یا الگوی دقیق در این فایل وجود دارد؟»«کجای کدبیس این مفهوم پیاده‌سازی شده است؟»
سرعتبرای الگوهای شناخته‌شده فوق‌العاده سریع. برای پردازش خام متن بهینه شده.کندتر، اما می‌تواند کوئری‌های پیچیده و انتزاعی انجام دهد که grep از عهده‌شان برنمی‌آید.
همه‌جا حضوریجهانی. به‌صورت پیش‌فرض روی تقریباً هر سیستم شبه‌یونیکسی موجود است.وابسته به پلتفرم. نیاز به نصب، پیکربندی و اغلب اتصال شبکه دارد.

جستجوی کد: اگر لازم است هر نمونه از نام تابع getUserById را پیدا کنید، grep -r "getUserById" ابزار کامل است. اما اگر لازم است همه جاهایی را در یک کدبیس بزرگ پیدا کنید که ریست رمز عبور کاربر را مدیریت می‌کنند چه؟ توابع مرتبط ممکن است resetUserPassword، updateCredentials یا handleAuthTokenInvalidation نام داشته باشند. grep نیازمند آن است که هر جایگشت ممکن را بدانید و جستجو کنید. ابزار قدرت‌گرفته از AI مفهوم ریست رمز عبور را می‌فهمد. می‌توانید ازش بپرسید: «توابع مرتبط با ریست رمز عبور را نشانم بده» و همه بلوک‌های کد مرتبط را فارغ از نام مشخص‌شان شناسایی می‌کند.

تحلیل لاگ: استفاده از grep "FATAL" برای پیدا کردن خطاهای حیاتی در فایل لاگ، کار روزانه بسیاری از مهندسان است. برای پیدا کردن مشکلات شناخته‌شده سریع و مؤثر است. اما یک مسئله مخرب‌تر را در نظر بگیرید: نشت حافظه ظریفی که عملکرد سیستم را طی چند روز تنزل می‌دهد. هیچ خط «ERROR» منفردی وجود ندارد. مشکل داخل الگویی از هزاران ورودی لاگ به‌ظاهر عادی پنهان شده است. اینجاست که پلتفرم‌های تحلیل لاگ مبتنی بر AI می‌درخشند. آن‌ها می‌توانند ترابایت‌ها داده لاگ را هضم و ناهنجاری‌های آماری را تشخیص دهند؛ و بفهمند که یک توالی خاص از رویدادها، با اینکه خودش خطا نیست، با افزایش مصرف حافظه همبستگی دارد. grep به شما کمک می‌کند سوزن‌هایی را که می‌دانید در انبار کاه هستند پیدا کنید؛ AI به شما کمک می‌کند سوزن‌هایی را کشف کنید که هرگز نمی‌دانستید وجود دارند.

خطاهای رایج و دیباگ

۱. استفاده از عملگرهای regex مثل *، + یا ? بدون escape کردن

هنگام استفاده از عملگرهای regex مثل *، + یا ؟، escape کردن درست آن‌ها برای اجتناب از تطبیق‌های غیرمنتظره ضروری است. مثلاً اگر می‌خواهید با کاراکتر تحت‌اللفظی * تطبیق یابید، باید آن را با بک‌اسلش escape کنید (\*). به‌طور مشابه، برای تطبیق کاراکترهای تحت‌اللفظی + یا ؟، آن‌ها را با بک‌اسلش escape کنید (\+ یا \?).

دستور نمونه برای تطبیق کاراکتر تحت‌اللفظی *:

grep -E "a\*" yourfile.txt

۲. تطبیق خطوط خالی یا خطوطی که فقط فاصله سفید دارند

برای تطبیق خطوط خالی یا خطوطی که فقط فاصله سفید دارند، از این الگوی regex استفاده کنید:

grep -E "^\s*$" yourfile.txt

این الگو با خطوطی تطبیق می‌یابد که شروع (^) و پایان ($)شان با هر کاراکتر فاصله سفیدی (\s*) است.

۳. جستجوی تب (\t) و بازگشت کرزی (\r)

برای تطبیق تب‌ها یا بازگشت کرزی (Carriage Return) در متن‌تان، می‌توانید از این دستورات استفاده کنید:

# تطبیق خطوط حاوی تب
grep -E "\t" yourfile.txt

# تطبیق خطوط حاوی بازگشت کرزی
grep -E "\r" yourfile.txt

توجه کنید که در برخی موارد ممکن است لازم باشد از گزینه -E برای فعال کردن الگوهای regex گسترش‌یافته استفاده کنید که امکان استفاده از قابلیت‌های پیشرفته‌تر regex را می‌دهد.

تفاوت‌های grep، egrep و fgrep

دستورتوضیحقابلیت‌هاموارد استفادهدستور نمونه
grepتطبیق الگوی پایهاز regex پایه پشتیبانی می‌کندتطبیق الگوی عمومیgrep "pattern" file.txt
egrepتطبیق الگوی گسترش‌یافتهاز regex گسترش‌یافته پشتیبانی می‌کندتطبیق الگوی پیچیدهegrep "pattern" file.txt
fgrepتطبیق الگوی ثابتبدون پشتیبانی از regexتطبیق رشته‌های ثابتfgrep "pattern" file.txt

نکته: تفاوت اصلی بین این دستورات، نوع تطبیق الگویی است که پشتیبانی می‌کنند. grep از regex پایه، egrep از regex گسترش‌یافته و fgrep اصلاً از regex پشتیبانی نمی‌کند.

مدیریت الگوهای چندخطی

grep به‌دلیل ماهیت خط‌محورش برای مدیریت الگوهای چندخطی (Multiline) مناسب نیست. اما ابزارهای جایگزینی وجود دارند که می‌توانند چنین الگوهایی را مؤثرانه مدیریت کنند. awk و perl دو گزینه محبوب‌اند که می‌توان برای جستجوی الگوهای در گستره چند خط استفاده کرد.

awk یک ابزار قدرتمند پردازش متن است که می‌تواند الگوها را در چند خط تطبیق دهد. به شما اجازه می‌دهد الگویی برای تطبیق تعریف کنید و سپس روی خطوط تطبیق‌یافته عملیاتی انجام دهید. مثلاً برای پیدا کردن خطوطی که الگویی در چند خط دارند، از این دستور استفاده کنید:

awk '/pattern/ {print $0}' yourfile.txt

این دستور همه خطوطی را که با الگوی مشخص‌شده تطبیق دارند چاپ می‌کند. توجه کنید awk را می‌توان برای عملیات پیچیده‌تری روی خطوط تطبیق‌یافته هم استفاده کرد؛ مانند چاپ کل بلوک متنی که با الگو مطابقت دارد.

perl ابزار قدرتمند دیگری است که می‌توان برای مدیریت الگوهای چندخطی استفاده کرد. روشی انعطاف‌پذیرتر و بیان‌غنی‌تر برای تطبیق الگوها با موتور داخلی عبارات باقاعده‌اش ارائه می‌دهد. مثلاً می‌توانید از این دستور برای پیدا کردن خطوطی که الگویی در چند خط دارند استفاده کنید:

perl -0777 -ne 'print if /pattern/s' yourfile.txt

این دستور به perl می‌گوید فایل را در حالت «slurp» بخواند (-0777) که امکان خواندن کل فایل را یک‌جا در حافظه فراهم می‌کند. گزینه -ne مشخص می‌کند که اسکریپت برای هر خط فایل اجرا شود. عبارت print if /pattern/s الگو را در چند خط تطبیق می‌دهد (به‌دلیل اصلاح‌کننده s) و کل بلوک متنی مطابقت‌یافته را چاپ می‌کند.

هم awk و هم perl وقتی بحث مدیریت الگوهای چندخطی می‌شود، قابلیت‌ها و انعطاف بیشتری از grep ارائه می‌دهند و برای چنین وظایفی گزینه‌های ایده‌آلی هستند.

سوالات متداول

۱. تفاوت grep و egrep چیست؟

grep و egrep هر دو برای تطبیق الگو استفاده می‌شوند، اما در نوع الگوهایی که پشتیبانی می‌کنند تفاوت دارند. grep از عبارات باقاعده پایه پشتیبانی می‌کند، در حالی که egrep از عبارات باقاعده گسترش‌یافته پشتیبانی می‌کند که امکان تطبیق الگوی پیشرفته‌تری را می‌دهد.

۲. آیا می‌توانم با grep در چند فایل جستجو کنم؟

بله، می‌توانید با مشخص کردن چند نام فایل یا استفاده از وایلدکارت با grep در چند فایل جستجو کنید. مثلاً:

grep "pattern" file1.txt file2.txt

یا

grep "pattern" *.txt

۳. چطور با grep خطوطی را پیدا کنم که با الگو مطابقت ندارند؟

برای این کار، از گزینه -v استفاده کنید. مثلاً:

grep -v "pattern" yourfile.txt

این دستور همه خطوطی را چاپ می‌کند که الگوی مشخص‌شده را ندارند.

۴. چطور شماره خطوط را در خروجی grep بگنجانم؟

برای گنجاندن شماره خطوط در خروجی grep، از گزینه -n استفاده کنید. مثلاً:

grep -n "pattern" yourfile.txt

این دستور شماره خطوط را به‌همراه خطوط مطابقت‌یافته با الگوی مشخص‌شده چاپ می‌کند.

۵. چرا regex من در grep طبق انتظار کار نمی‌کند؟

ممکن است چند دلیل وجود داشته باشد که regex شما در grep طبق انتظار کار نمی‌کند. چند مشکل رایج برای بررسی:

  • مطمئن شوید از سینتکس درست الگوی regex استفاده می‌کنید.
  • مطمئن شوید گزینه‌های درست دستور grep را استفاده می‌کنید (مثلاً -E برای regex گسترش‌یافته).
  • بررسی کنید الگوی شما حاوی کاراکترهای خاصی است که نیاز به escape دارند.
  • تأیید کنید که الگوی شما درست کوتیشن شده تا از تفسیر توسط شل جلوگیری شود.

۶. چطور الگویی را جستجو کنم که شامل فاصله سفید یا کاراکترهای خاص است؟

برای جستجوی الگویی که شامل فاصله سفید یا کاراکترهای خاص است، باید این کاراکترها را در الگوی regex به‌درستی escape کنید. مثلاً برای جستجوی الگویی که فاصله سفید دارد، از این دستور استفاده کنید:

grep "pattern\ with\ whitespace" yourfile.txt

به‌طور مشابه، برای جستجوی الگویی که کاراکترهای خاص دارد، آن‌ها را با بک‌اسلش (\) escape کنید. مثلاً:

grep "pattern\ with\ special\ characters" yourfile.txt

نتیجه‌گیری

در این/tutorial (آموزش)، از جستجوهای ساده کلیدواژه‌ای فراتر رفتید و grep را به‌عنوان ابزاری قدرتمند برای پردازش متن به کار گرفتید. با تطبیق تحت‌اللفظی پایه و گزینه‌های رایج خط فرمان شروع کردید، بعد از میان گونه‌های مختلف عبارات باقاعده—از پایه (BRE) و گسترش‌یافته (ERE) گرفته تا الگوهای پیشرفته موجود در عبارات باقاعده سازگار با پرل (PCRE)—عبور کردید. با کاوش در سناریوهای دنیای واقعی مثل فیلتر کردن لاگ‌ها، اسکن سورس‌کد و آماده‌سازی داده برای روندهای AI، دیدید که grep چگونه ابزاری ضروری در هر جعبه‌ابزار مدرنی باقی می‌ماند.

تسلط بر grep و سینتکس عبارات باقاعده‌اش یک مهارت بنیادی است که توانایی‌تان برای کار با داده‌های متنی در خط فرمان را به‌طور چشمگیری افزایش می‌دهد. به شما اجازه می‌دهد روندهای کاری کارآمد، دقیق و خودکار بسازید و وظایف پیچیده الک کردن داده را به دستوراتی ساده تبدیل کنید.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا