خوش آموز درخت تو گر بار دانش بگیرد، به زیر آوری چرخ نیلوفری را


نحوه استفاده از sed برای یافتن و جایگزینی رشته در فایل ها

نحوه استفاده از sed برای یافتن و جایگزینی رشته در فایل ها
در برخی موارد وقتی که با فایل های متنی یا text کار می کنید شاید نیاز به این داشته باشید که متن مورد نظرتان را در چندین فایل پیدا کرده و رشته هایی را جایگزین انها کنید.

نرم افزار سامانه مودیان راهکار
sed یک stream editor می باشد. sed می تواند دستکاری متن اولیه را روی فایل ها و جریان های ورودی مانند pipeline ها انجام دهد. با sed می توانید کلمات و خطوط را جستجو، یافته و جایگزین، ثبت و حذف کنید. از regular expression های پایه ای و ساده تا توسعه یافته پشتیبانی می کند که به شما امکان می دهد الگوهای پیچیده را مطابقت دهید. یعنی بر اساس الگوهای پیچیده سرچ را داشته باشید.


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

Find and Replace String with sed

نسخه های مختلفی از sed وجود دارد که تفاوت های functional و عملکردی بین آنها وجود دارد. macOS از نسخه BSD استفاده می کند، در حالی که اکثر توزیع های لینوکس به طور پیش فرض با GNU sed از پیش نصب شده عرضه می شوند. ما از نسخهGNU استفاده خواهیم کرد.
شکل کلی سرچ و جایگزینی متن با استفاده از sed به صورت زیر است:

sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE

گزینه i- بصورت پیشفرض خروجی sed را در یک خروجی استاندارد می نویسد. این گزینه به sed دستور می دهد که فایل ها را در جای خود ویرایش کند. اگر هم که پسوندی معرفی شده باشد(مثلا i.bak-)، یک بک آپ از فایل اصلی تهیه می کند.
S پراستفاده ترین گزینه در دستور فوق است که متن جایگزین است.
/// کاراکترهای جداکننده هستند که البته می تواند هر کاراکتری باشد ولی بصورت پیشفرض اسلش می باشد.
SEARCH_REGEX در واقع یک رشته معمولی و یا regular expression برای سرچ می باشد.
REPLACEMENT در واقع همان رشته جایگزین است.
g- به طور پیش‌فرض، sed فایل را خط به خط می‌خواند و تنها اولین رخداد SEARCH_REGEX را در یک خط تغییر می‌دهد. هنگامی که از این flag در دستور استفاده کرده باشید، این تغییر را بصورت کلی و نه فقط در اولین رخداد، اعمال می کند.
INPUTFILE - نام فایلی که می خواهید دستور را روی آن اجرا کنید.

خب، حالا اجازه دهید کمی با دستور sed کار کنیم و از دستور sed برای جستجو و جایگزینی متن در فایل ها با برخی از رایج ترین گزینه ها استفاده کنیم.
مثلا ما یک فایل متنی با محتوای زیر داریم و نام فایل ما file.txt است:

123 Foo foo foo
foo /bin/bash Ubuntu foobar 456

این فایل در هر جایی از سیستم تان می توانید ایجاد کنید و در خط فرمان حتما با دستور cd به آن دایرکتوری بروید.
در دستور زیر از g استفاده نمی کنیم و خواهید دید که فقط اولین تطبیق اعمال می شود و به کل فایل ما اعمال نخواهد شد.

sed -i 's/foo/linux/' file.txt

خروجی دستور فوق را در زیر مشاهده خواهید کرد:

123 Foo linux foo
linux /bin/bash Ubuntu foobar 456

توجه داشته باشید که sed دستوری Casesensitive بوده و حساس به حروف بزرگ و کوچک است.
حالا در دستور g را هم قرار می دهیم تا نه فقط به تطبیق اول، بلکه در کل متن اگر موردی یافت شد، متن مورد نظر ما را جایگزین کند.

sed -i 's/foo/linux/g' file.txt

123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456

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

sed -i 's/\bfoo\b/linux/g' file.txt

123 Foo linux linux
linux /bin/bash Ubuntu foobar 456

با استفاده از I می توانید حساسیت به حروف بزرگ و کوچک را بردارید. در این مثال هم g و هم از I استفاده شده است:

sed -i 's/foo/linux/gI' file.txt

123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456

اگر می‌خواهید رشته‌ای را یافته و جایگزین کنید که حاوی کاراکتر جداکننده (/) است، باید از بک اسلش (\) برای فرار از اسلش استفاده کنید. به عنوان مثال برای جایگزینی /bin/bash با /usr/bin/zsh باید دستور را بصورت زیر اجرا کنید:

sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt

گزینه ساده تر و بسیار خواناتر استفاده از یک کاراکتر جداکننده دیگر است. اکثر کاربران از نوار عمودی (|) یا دو نقطه (:) استفاده می کنند، اما شما می توانید از هر کاراکتر دیگری استفاده کنید:

123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456

حتی از regular expression ها هم می توانید استفاده کنید. به عنوان مثال، برای جستجوی تمام اعداد 3 رقمی و جایگزینی آنها با Number به صورت زیر دستور را اجرا کنید:

sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt

number Foo foo foo
foo /bin/bash demo foobar number

یکی دیگر از ویژگی های مفید sed این است که می توانید از کاراکتر & مثلا بصورت زیر استفاده کنید. در مثال زیر می خواهیم اطرلف هر عدد سه رقمی {} اضافه کنیم.

sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt

{123} Foo foo foo
foo /bin/bash demo foobar {456}

همیشه ایده خوبی است که هنگام ویرایش یک فایل با sed یک نسخه پشتیبان تهیه کنید. برای انجام این کار، فقط یک پسوند برای فایل پشتیبان به گزینه i- ارائه دهید. به عنوان مثال، برای ویرایش file.txt و ذخیره فایل اصلی به عنوان file.txt.bak دستور زیر را اجرا کنید.

sed -i.bak 's/foo/linux/g' file.txt

بعضا شاید بخواهید به صورت بازگشتی دایرکتوری ها را برای فایل های حاوی یک رشته خاص جستجو کنید و رشته را در همه فایل ها جایگزین کنید. این مورد را می توان با استفاده از دستوراتی مانند find یا grep برای یافتن بازگشتی فایل ها در دایرکتوری و pipe کردن نام فایل ها به sed انجام داد. دستور زیر به صورت بازگشتی فایل‌ها را در دایرکتوری جاری جستجو می‌کند و نام فایل‌ها را به sed ارسال می‌کند.

find . -type f -exec sed -i 's/foo/bar/g' {} +

برای جلوگیری از مشکلات مربوط به فایل‌هایی که در نامشان جای خالی یا space دارند، از گزینه -print0 استفاده کنید، که به find می‌گوید نام فایل را پرینت کند، به دنبال آن یک کاراکتر فاصله و خروجی را با استفاده از xargs -0 به sed منتقل کنید:

find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

برای Exclude کردن یک دایرکتوری از not- path- استفاده کنید. برای مثال، اگر رشته‌ای را در مخزن git لوکال خود جایگزین می‌کنید و همه فایل‌هایی که با نقطه شروع می شوند را Exclude کنید از دستور زیر استفاده کنید:

find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'

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

find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'

گزینه دیگر استفاده از دستور grep برای یافتن بازگشتی همه فایل های حاوی الگوی سرچ و سپس pipe کردن نام فایل ها به sed است:

grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'

نمایش دیدگاه ها (1 دیدگاه)

دیدگاه خود را ثبت کنید:

انتخاب تصویر ویرایش حذف
توجه! حداکثر حجم مجاز برای تصویر 500 کیلوبایت می باشد.


دسته بندی مطالب خوش آموز