كيفية استخدام الأمر sed على لينكس
قد يبدو الأمر مجنونًا ، لكن sed
أمر Linux هو محرر نصوص بدون واجهة. يمكنك استخدامه من سطر الأوامر لمعالجة النص في الملفات والتدفق. سنوضح لك كيفية تسخير قوتها.
قوة سيد
و sed
الأمر يشبه لعبة الشطرنج: يستغرق ساعة لتعلم أساسيات ومدى الحياة للسيطرة عليها (أو على الأقل الكثير من الممارسة). سنعرض لك مجموعة مختارة من المناورات الافتتاحية في كل فئة من فئات sed
الوظائف الرئيسية .
sed
هو محرر دفق يعمل على مدخلات أو ملفات نصية. ومع ذلك ، لا يحتوي على واجهة محرر نصوص تفاعلية. بدلاً من ذلك ، أنت تقدم تعليمات لها لاتباعها أثناء عملها من خلال النص. كل هذا يعمل في Bash وقذائف سطر الأوامر الأخرى.
مع sed
يمكنك أن تفعل كل مما يلي:
- اختر نص
- نص بديل
- أضف أسطرًا إلى النص
- حذف أسطر من النص
- تعديل (أو الاحتفاظ) ملف أصلي
لقد صممنا أمثلةنا لتقديم وإثبات المفاهيم ، وليس لإنتاج الأوامر الأكثر توتراً (والأقل سهولة) sed
. ومع ذلك ، فإن وظائف مطابقة النمط واختيار النص sed
تعتمد بشكل كبير على التعبيرات العادية (regexes). ستحتاج إلى بعض الإلمام بهذه الأشياء للحصول على أفضل النتائج sed
.
ذات صلة: كيفية استخدام التعبيرات العادية (regexes) على Linux
مثال بسيط
أولاً ، سنستخدم echo
لإرسال بعض النص sed
عبر أنبوب ، sed
واستبدال جزء من النص. للقيام بذلك ، نكتب ما يلي:
صدى howtogonk | sed 's / gonk / geek /'
و echo
يرسل قيادة "howtogonk" إلى sed
، وحكمنا استبدال بسيطة يتم تطبيق (في "ليالي" لتقف على الاستبدال). sed
يبحث في نص الإدخال عن تكرار السلسلة الأولى ، وسيحل محل أي مطابقات مع الثانية.
يتم استبدال السلسلة "gonk" بـ "geek" ، ويتم طباعة السلسلة الجديدة في النافذة الطرفية.
من المحتمل أن تكون البدائل هي الاستخدام الأكثر شيوعًا لـ sed
. قبل أن نتمكن من التعمق في التبديلات ، نحتاج إلى معرفة كيفية تحديد النص ومطابقته.
اختيار النص
سنحتاج إلى ملف نصي لأمثلة لدينا. سنستخدم واحدة تحتوي على مجموعة من الأبيات من قصيدة صموئيل تايلور كوليردج الملحمية "صقعة الملاح القديم"
نكتب ما يلي لإلقاء نظرة عليه less
:
أقل coleridge.txt
لتحديد بعض الأسطر من الملف ، نقدم سطري البداية والنهاية للنطاق الذي نريد تحديده. رقم واحد يحدد هذا السطر الواحد.
لاستخراج الأسطر من واحد إلى أربعة ، نكتب هذا الأمر:
sed -n '1،4p' coleridge.txt
لاحظ الفاصلة بين 1
و 4
. و p
تعني "طباعة خطوط يقابل". بشكل افتراضي ، sed
يطبع كل الأسطر. سنرى كل النص في الملف مع طباعة الأسطر المتطابقة مرتين. لمنع هذا ، سنستخدم الخيار -n
(الصامت) لمنع النص غير المتطابق.
نقوم بتغيير أرقام الأسطر حتى نتمكن من اختيار آية مختلفة كما هو موضح أدناه:
sed -n '6،9p' coleridge.txt
يمكننا استخدام -e
خيار (التعبير) لعمل تحديدات متعددة. باستخدام تعبيرين ، يمكننا اختيار آيتين ، على النحو التالي:
sed -n -e '1،4p' -e '31، 34p 'coleridge.txt
إذا قللنا الرقم الأول في التعبير الثاني ، فيمكننا إدخال فراغ بين الآيتين. نكتب ما يلي:
sed -n -e '1،4p' -e '30، 34p 'coleridge.txt
يمكننا أيضًا اختيار سطر البداية وإخبارنا sed
بالمرور عبر الملف وطباعة الأسطر البديلة ، كل سطر خامس ، أو تخطي أي عدد من الأسطر. الأمر مشابه لتلك التي استخدمناها أعلاه لتحديد نطاق. ولكن هذه المرة ، سنستخدم علامة التلدة ( ~
) بدلاً من الفاصلة لفصل الأرقام.
الرقم الأول يشير إلى خط البداية. الرقم الثاني يخبرنا عن sed
الأسطر بعد خط البداية التي نريد رؤيتها. الرقم 2 يعني كل سطر ثاني ، و 3 يعني كل سطر ثالث ، وهكذا.
نكتب ما يلي:
sed -n '1 ~ 2p' coleridge.txt
لن تعرف دائمًا مكان النص الذي تبحث عنه في الملف ، مما يعني أن أرقام الأسطر لن تكون مفيدة دائمًا. ومع ذلك ، يمكنك أيضًا استخدامها sed
لتحديد الأسطر التي تحتوي على أنماط نص متطابقة. على سبيل المثال ، لنستخرج كل الأسطر التي تبدأ بـ "و".
علامة الإقحام ( ^
) تمثل بداية السطر. سنرفق مصطلح البحث الخاص بنا بشرطة أمامية مائلة ( /
). نقوم أيضًا بتضمين مسافة بعد "And" لذلك لن يتم تضمين كلمات مثل "Android" في النتيجة.
sed
يمكن أن تكون قراءة النصوص صعبة بعض الشيء في البداية. و /p
تعني "طباعة"، تماما كما فعلت في الأوامر كنا أعلاه. في الأمر التالي ، على الرغم من ذلك ، تسبقه شرطة مائلة للأمام:
sed -n '/ ^ و / p' coleridge.txt
يتم استخراج ثلاثة أسطر تبدأ بحرف "And" من الملف وعرضها لنا.
إجراء الاستبدالات
في مثالنا الأول ، أظهرنا لك التنسيق الأساسي التالي sed
للاستبدال:
صدى howtogonk | sed 's / gonk / geek /'
و s
يقول sed
هذا هو تبديل. السلسلة الأولى هي نمط البحث ، والثانية هي النص الذي نريد استبدال النص المتطابق به. بالطبع ، كما هو الحال مع كل ما يتعلق بـ Linux ، فإن الشيطان يكمن في التفاصيل.
نكتب ما يلي لتغيير كل تكرارات "اليوم" إلى "الأسبوع" ، ونمنح الملاح والقطرس مزيدًا من الوقت للترابط:
sed -n 's / day / week / p' coleridge.txt
في السطر الأول ، يتم تغيير التكرار الثاني فقط لـ "اليوم". هذا بسبب sed
التوقف بعد المباراة الأولى في كل سطر. يتعين علينا إضافة "g" في نهاية التعبير ، كما هو موضح أدناه ، لإجراء بحث عالمي حتى تتم معالجة جميع المطابقات في كل سطر:
sed -n 's / day / week / gp' coleridge.txt
هذا يطابق ثلاثة من أربعة في السطر الأول. نظرًا لأن الكلمة الأولى هي "اليوم" ، sed
وهي حساسة لحالة الأحرف ، فلا تعتبر هذه الحالة هي نفسها كلمة "اليوم".
نكتب ما يلي ، نضيف i
الأمر في نهاية التعبير للإشارة إلى عدم الحساسية لحالة الأحرف:
sed -n 's / day / week / gip' coleridge.txt
يعمل هذا ، ولكن قد لا ترغب دائمًا في تشغيل الحساسية لحالة الأحرف لكل شيء. في هذه الحالات ، يمكنك استخدام مجموعة regex لإضافة حساسية حالة خاصة بالنمط.
على سبيل المثال ، إذا وضعنا أحرفًا بين قوسين مربعين ( []
) ، فسيتم تفسيرها على أنها "أي حرف من قائمة الأحرف هذه".
نكتب ما يلي ، ونقوم بتضمين "D" و "d" في المجموعة ، للتأكد من تطابقها مع كل من "اليوم" و "اليوم":
sed -n 's / [Dd] ay / week / gp' coleridge.txt
يمكننا أيضًا تقييد الاستبدالات على أقسام من الملف. لنفترض أن ملفنا يحتوي على مسافات غريبة في المقطع الأول. يمكننا استخدام الأمر المألوف التالي لرؤية الآية الأولى:
sed -n '1،4p' coleridge.txt
سنبحث عن مسافتين ونستبدلهما بمساحة واحدة. سنفعل هذا بشكل عام حتى يتكرر الإجراء عبر الخط بأكمله. للتوضيح ، فإن نمط البحث هو مسافة ، وعلامة النجمة الفضائية ( *
) ، وسلسلة الاستبدال هي مسافة واحدة. و 1,4
يقيد استبدال لأربعة أسطر الأولى من الملف.
نجمع كل ذلك معًا في الأمر التالي:
sed -n '1،4 s / * / / gp' coleridge.txt
هذا يعمل بشكل جيد! نمط البحث هو المهم هنا. تمثل العلامة النجمية ( *
) صفرًا أو أكثر من الحرف السابق ، وهو مسافة. وبالتالي ، فإن نمط البحث يبحث عن سلاسل بمساحة واحدة أو أكثر.
إذا استبدلنا مسافة واحدة بأي تسلسل من مسافات متعددة ، فسنقوم بإعادة الملف إلى مسافات منتظمة ، بمسافة واحدة بين كل كلمة. سيؤدي هذا أيضًا إلى استبدال مسافة واحدة بمسافة واحدة في بعض الحالات ، لكن هذا لن يؤثر على أي شيء سلبًا - سنظل نحصل على النتيجة المرجوة.
إذا كتبنا ما يلي وقمنا بتقليص نمط البحث إلى مسافة واحدة ، فسترى على الفور سبب ضرورة تضمين مسافتين:
sed -n '1،4 s / * / / gp' coleridge.txt
نظرًا لأن علامة النجمة تطابق صفرًا أو أكثر من الحرف السابق ، فإنها ترى كل حرف ليس مسافة على أنه "مسافة صفرية" ويطبق الاستبدال عليه.
ومع ذلك ، إذا قمنا بتضمين مسافتين في نمط البحث ، sed
فيجب إيجاد حرف مسافة واحد على الأقل قبل تطبيق الاستبدال. هذا يضمن أن الأحرف غير المسافات ستبقى كما هي.
نكتب ما يلي ، باستخدام -e
(التعبير) الذي استخدمناه سابقًا ، والذي يسمح لنا بإجراء استبداليين أو أكثر في وقت واحد:
sed -n -e 's / motion / flutter / gip' -e 's / ocean / gutter / gip' coleridge.txt
يمكننا تحقيق نفس النتيجة إذا استخدمنا فاصلة منقوطة ( ;
) لفصل التعبيرين ، مثل:
sed -n 's / motion / flutter / gip؛ s / ocean / gutter / gip' coleridge.txt
عندما استبدلنا "يوم" بـ "أسبوع" في الأمر التالي ، تم أيضًا تبديل مثيل "اليوم" في التعبير "جيدًا في اليوم":
sed -n 's / [Dd] ay / week / gp' coleridge.txt
لمنع هذا ، يمكننا فقط محاولة الاستبدال على الأسطر التي تتطابق مع نمط آخر. إذا قمنا بتعديل الأمر ليكون لدينا نمط بحث في البداية ، فسننظر فقط في العمل على الأسطر التي تطابق هذا النمط.
نكتب ما يلي لجعل نمط المطابقة الخاص بنا هو الكلمة "بعد":
sed -n '/ after / s / [Dd] ay / week / gp' coleridge.txt
هذا يعطينا الاستجابة التي نريدها.
المزيد من البدائل المعقدة
لنمنح Coleridge فاصلًا ونستخدمه sed
لاستخراج الأسماء من etc/passwd
الملف.
هناك طرق أقصر للقيام بذلك (المزيد عن ذلك لاحقًا) ، لكننا سنستخدم الطريقة الأطول هنا لتوضيح مفهوم آخر. يمكن ترقيم كل عنصر مطابق في نمط البحث (يسمى التعبيرات الفرعية) (بحد أقصى تسعة عناصر). يمكنك بعد ذلك استخدام هذه الأرقام في sed
أوامرك للإشارة إلى تعبيرات فرعية معينة.
يجب عليك إرفاق التعبير الفرعي بين قوسين [ ()
] حتى يعمل هذا. يجب أيضًا أن يسبق الأقواس بشرطة مائلة للخلف ( \
) لمنع معاملتها كحرف عادي.
للقيام بذلك ، يمكنك كتابة ما يلي:
sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd
دعنا نقسم هذا:
sed 's/
: إنsed
القيادة وبداية التعبير تبديل.\(
: قوس الفتح [(
] الذي يحتوي على التعبير الفرعي مسبوقًا بشرطة مائلة للخلف (\
).[^:]*
: يحتوي التعبير الفرعي الأول لمصطلح البحث على مجموعة بين قوسين مربعين. علامة الإقحام (^
) تعني "لا" عند استخدامها في مجموعة. تعني المجموعة أن أي حرف ليس علامة النقطتين (:
) سيتم قبوله كمطابقة.\)
: قوس الإغلاق [)
] بشرطة مائلة للخلف (\
)..*
: هذا التعبير الفرعي للبحث الثاني يعني "أي حرف وأي عدد منهم"./\1
: يحتوي جزء الاستبدال من التعبير1
مسبوقًا بشرطة مائلة للخلف (\
). هذا يمثل النص الذي يطابق التعبير الفرعي الأول./'
: إغلاق الشرطة المائلة للأمام (/
) والاقتباس الفردي ('
) ينهيsed
الأمر.
ما يعنيه هذا كله هو أننا سنبحث عن أي سلسلة من الأحرف لا تحتوي على نقطتين ( :
) ، والتي ستكون أول مثيل لنص مطابق. بعد ذلك ، نبحث عن أي شيء آخر في هذا السطر ، والذي سيكون المثال الثاني لنص مطابق. سنقوم باستبدال السطر بأكمله بالنص الذي يطابق التعبير الجزئي الأول.
/etc/passwd
يبدأ كل سطر في الملف باسم مستخدم منتهي بنقطتين. نطابق كل شيء حتى النقطة الأولى ، ثم نستبدل هذه القيمة بالسطر بأكمله. لذلك ، قمنا بعزل أسماء المستخدمين.
بعد ذلك ، سنضع التعبير الفرعي الثاني بين قوسين [ ()
] حتى نتمكن من الإشارة إليه بالرقم أيضًا. سنستبدل أيضًا \1
بـ \2
. سيحل أمرنا الآن محل السطر بأكمله بكل شيء بدءًا من النقطة الأولى ( :
) وحتى نهاية السطر.
نكتب ما يلي:
sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd
هذه التغييرات الصغيرة تقلب معنى الأمر ، ونحصل على كل شيء باستثناء أسماء المستخدمين.
الآن ، دعنا نلقي نظرة على الطريقة السريعة والسهلة للقيام بذلك.
مصطلح البحث الخاص بنا يبدأ من النقطة الأولى ( :
) إلى نهاية السطر. نظرًا لأن تعبير الاستبدال فارغ ( //
) ، فلن نستبدل النص المطابق بأي شيء.
لذلك ، نكتب ما يلي ، ونقطع كل شيء من أول علامة ( :
) إلى نهاية السطر ، مع ترك أسماء المستخدمين فقط:
sed 's /:.*// "/ etc / passwd
لنلقِ نظرة على مثال نشير فيه إلى المطابقتين الأولى والثانية في نفس الأمر.
لدينا ملف من الفواصل ( ,
) يفصل بين الاسمين الأول والأخير. نريد إدراجها على أنها "اسم العائلة ، الاسم الأول". يمكننا استخدام cat
، كما هو موضح أدناه ، لمعرفة ما يوجد في الملف:
القط geeks.txt
مثل الكثير من sed
الأوامر ، قد يبدو الأمر التالي غير قابل للاختراق في البداية:
sed 's / ^ \ (. * \)، \ (. * \) $ / \ 2، \ 1 / g' geeks.txt
هذا أمر استبدال مثل الآخرين الذي استخدمناه ، ونمط البحث سهل للغاية. سنقوم بتفصيلها أدناه:
sed 's/
: أمر الاستبدال العادي.^
: نظرًا لأن علامة الإقحام ليست في مجموعة ([]
) ، فهذا يعني "بداية السطر".\(.*\),
: أول تعبير فرعي هو أي عدد من أي حرف. إنه محاط بأقواس [()
] ، يسبق كل منهما شرطة مائلة للخلف (\
) حتى نتمكن من الإشارة إليه برقم. يُترجم نمط البحث بالكامل حتى الآن على أنه بحث من بداية السطر حتى الفاصلة الأولى (,
) لأي عدد من أي حرف.\(.*\)
: التعبير الفرعي التالي (مرة أخرى) هو أي رقم من أي حرف. كما أنه محاط بأقواس [()
] ، وكلاهما مسبوق بشرطة مائلة للخلف (\
) حتى نتمكن من الإشارة إلى النص المطابق برقم.$/
: تمثل علامة الدولار ($
) نهاية السطر وستسمح لبحثنا بالاستمرار حتى نهاية السطر. لقد استخدمنا هذا ببساطة لتقديم علامة الدولار. لا نحتاجها هنا حقًا ، حيث*
ستنتقل العلامة النجمية ( ) إلى نهاية السطر في هذا السيناريو. الشرطة المائلة للأمام (/
) تكمل قسم نمط البحث.\2,\1 /g'
: نظرًا لأننا وضعنا التعبيرين الفرعيين بين قوسين ، فيمكننا الإشارة إلى كلاهما بأرقامهما. لأننا نريد عكس الترتيب ، نكتبها كـsecond-match,first-match
. الأرقام يجب أن تكون مسبوقة بشرطة مائلة للخلف (\
)./g
: هذا يتيح لقيادتنا العمل عالميًا على كل سطر.geeks.txt
: الملف الذي نعمل عليه.
يمكنك أيضًا استخدام أمر القص ( c
) لاستبدال الأسطر الكاملة التي تطابق نمط البحث الخاص بك. نكتب ما يلي للبحث عن سطر بداخله كلمة "عنق" ، واستبداله بسلسلة نصية جديدة:
sed '/ neck / c حول معصمي كان مشدودًا' coleridge.txt
يظهر خطنا الجديد الآن في الجزء السفلي من المستخلص.
إدخال الأسطر والنص
يمكننا أيضًا إدراج أسطر ونصوص جديدة في ملفنا. لإدراج أسطر جديدة بعد أي أسطر متطابقة ، سنستخدم الأمر إلحاق ( a
).
هذا هو الملف الذي سنعمل معه:
القط geeks.txt
لقد قمنا بترقيم الأسطر لتسهيل متابعة ذلك.
نكتب ما يلي للبحث عن الأسطر التي تحتوي على كلمة "هو" ، وإدراج سطر جديد تحتها:
sed '/ He / a -> مُدرج!' geeks.txt
نكتب ما يلي ونقوم بتضمين الأمر Insert Command ( i
) لإدراج السطر الجديد فوق تلك التي تحتوي على نص مطابق:
sed '/ He / i -> مُدرج!' geeks.txt
يمكننا استخدام علامة العطف ( &
) ، التي تمثل النص المطابق الأصلي ، لإضافة نص جديد إلى سطر مطابق. \1
، \2
وما إلى ذلك ، تمثل التعبيرات الفرعية المطابقة.
لإضافة نص إلى بداية السطر ، سنستخدم أمر استبدال يطابق كل شيء في السطر ، جنبًا إلى جنب مع عبارة بديلة تجمع بين النص الجديد والسطر الأصلي.
للقيام بكل هذا ، نكتب ما يلي:
sed 's /.*/--> تم إدراج & /' geeks.txt
نكتب ما يلي متضمنًا G
الأمر الذي سيضيف سطرًا فارغًا بين كل سطر:
sed 'G' geeks.txt
إذا كنت ترغب في إضافة اثنين أو أكثر من أسطر فارغة، يمكنك استخدام G;G
، G;G;G
وهلم جرا.
حذف الخطوط
يحذف الأمر Delete ( d
) الأسطر التي تطابق نمط البحث أو تلك المحددة بأرقام الأسطر أو النطاقات.
على سبيل المثال ، لحذف السطر الثالث ، نكتب ما يلي:
sed '3d' geeks.txt
لحذف نطاق الأسطر من أربعة إلى خمسة ، نكتب ما يلي:
sed '4،5d' geeks.txt
لحذف الأسطر خارج النطاق ، نستخدم علامة التعجب ( !
) ، كما هو موضح أدناه:
sed '6،7! d' geeks.txt
حفظ التغييرات الخاصة بك
حتى الآن ، تمت طباعة جميع نتائجنا في نافذة Terminal ، لكننا لم نحفظها في أي مكان بعد. لجعل هذه التغييرات دائمة ، يمكنك إما كتابة تغييراتك على الملف الأصلي أو إعادة توجيهها إلى ملف جديد.
الكتابة فوق ملفك الأصلي تتطلب بعض الحذر. إذا كان sed
الأمر الخاص بك خاطئًا ، فقد تقوم بإجراء بعض التغييرات على الملف الأصلي التي يصعب التراجع عنها.
لراحة البال ، sed
يمكنك إنشاء نسخة احتياطية من الملف الأصلي قبل أن ينفذ الأمر.
يمكنك استخدام الخيار في المكان ( -i
) لإخبار sed
كتابة التغييرات على الملف الأصلي ، ولكن إذا قمت بإضافة امتداد ملف إليه ، sed
فسيقوم بعمل نسخة احتياطية من الملف الأصلي إلى ملف جديد. سيكون له نفس اسم الملف الأصلي ، ولكن بامتداد ملف جديد.
للتوضيح ، سنبحث عن أي سطور تحتوي على كلمة "هو" ونحذفها. سنقوم أيضًا بعمل نسخة احتياطية من ملفنا الأصلي إلى ملف جديد باستخدام امتداد BAK.
للقيام بكل هذا ، نكتب ما يلي:
sed -i'.bak '' / ^.*He.*$/d 'geeks.txt
نكتب ما يلي للتأكد من أن ملف النسخ الاحتياطي الخاص بنا لم يتغير:
القط geeks.txt.bak
يمكننا أيضًا كتابة ما يلي لإعادة توجيه الإخراج إلى ملف جديد وتحقيق نتيجة مماثلة:
sed -i'.bak '' / ^.*He.*$/d 'geeks.txt> new_geeks.txt
نستخدم cat
لتأكيد كتابة التغييرات على الملف الجديد ، كما هو موضح أدناه:
القط new_geeks.txt
بعد كل هذا سيد
كما لاحظت على الأرجح ، حتى هذا التمهيدي السريع sed
طويل جدًا. هناك الكثير لهذا الأمر ، وهناك المزيد الذي يمكنك فعله به.
على الرغم من ذلك ، نأمل أن تكون هذه المفاهيم الأساسية قد وفرت أساسًا متينًا يمكنك البناء عليه مع استمرار تعلم المزيد.