۰۹بهمن
بخش دوم دستورات تک خطی sed با ۱۰ مثال پیش روی شماست . در این بخش دستورات داده شده اکثرا بر روی فایل data.txt با محتوای زیر اعمال می شوند.
# cat data.txt
This is line number: #3. line 1 and 2 is empty
This is line number: #4
This is line number: #5
This is line number: #6
This is line number: #7
This is line number: #9
This is line number: #10
This is line number: #13 . Note that line number 14 is empty
برای بررسی دقیق فایل بالا و اطلاع از خطوط خالی و تعداد خط ها با استفاده از دستور sed ابتدا و انتهای هر خط را با علامتهای > و < مشخص کرده و سپس با دستور nl کلیه خطوط خروجی را شماره گذاری می کنیم.
# sed 's/^/</;s/$/>/' data.txt | nl -ba
1 <>
2 <>
3 < This is line number: #3. line 1 and 2 is empty>
4 <This is line number: #4>
5 < This is line number: #5>
6 < This is line number: #6>
7 <This is line number: #7>
8 <>
9 < This is line number: #9 >
10 <This is line number: #10>
11 <>
12 <>
13 <This is line number: #13 . Note that line number 14 is empty>
14 <>
همانگونه که مشاهده می کنید خط ۱ و ۲ در ابتدای فایل و همچنین خط ۱۴ در انتهای فایل خالی می باشند. خطوط ۸ و ۱۱ و ۱۲ نیز خالی می باشند. خطوط ۳ و ۵ و ۶ و ۹ با کاراکترهای space شروع می شوند و خط ۹ نیز به تعدادی کاراکتر space ختم می شود. حال که ساختار فایل ورودی به صورت شفاف شناخته شد ، مثالهایی از دستور sed را در ادامه بررسی می کنیم.
مثال ۱) کلیه خطوط خالی را حذف کنید.
# sed '/^$/ d' data.txt
This is line number: #3. line 1 and 2 is empty
This is line number: #4
This is line number: #5
This is line number: #6
This is line number: #7
This is line number: #9
This is line number: #10
This is line number: #13 . Note that line number 14 is empty
مثال ۲) خط های خالی را حذف کنید و آخرین کاراکتر هر خط غیر خالی را پاک کنید.
# sed '/^$/ d;s/.$//' data.txt
This is line number: #3. line 1 and 2 is empt
This is line number: #
This is line number: #
This is line number: #
This is line number: #
This is line number: #9
This is line number: #1
This is line number: #13 . Note that line number 14 is empt
برای بررسی صحت عملکرد دستور به کاراکترهای پایان هر خط توجه کنید .
مثال ۳) شماره هر خط را در سمت چپ همان خط نمایش دهید.
# sed '=' data.txt | sed 'N;s/\n/\t/'
1
2
3 This is line number: #3. line 1 and 2 is empty
4 This is line number: #4
5 This is line number: #5
6 This is line number: #6
7 This is line number: #7
8
9 This is line number: #9
10 This is line number: #10
11
12
13 This is line number: #13 . Note that line number 14 is empty
14
در مثال فوق دو بار sed را استفاده کرده ایم . دستور = که جز دستورات sed است شماره خط فعلی را به اضافه ی یک کاراکتر n\ یا new line در خروجی استاندارد می نویسد . برای اطلاع توجه داشته باشید که دستور = علی رغم استفاده از سوییچ n- باز هم شماره خط را در خروجی استاندارد می نویسد و یا به عبارت دیگر سوییچ n- تاثیری بر روی عملکرد دستور = ندارد. برای فهم دقیق دستور بالا ابتدا فقط قسمت اول دستور یا قسمت قبل از pipe آن را بررسی می کنیم.
# sed '=' data.txt
1
2
3
This is line number: #3. line 1 and 2 is empty
4
This is line number: #4
5
This is line number: #5
6
This is line number: #6
7
This is line number: #7
8
9
This is line number: #9
10
This is line number: #10
11
12
13
This is line number: #13 . Note that line number 14 is empty
14
همانطور که مشاهده می کنید دستور = شماره خط را در خروجی استاندارد می نویسد و سپس یک کاراکتر n\ چاپ می کند . از طرف دیگر sed به صورت خودکار بعد از اجرای تمام دستورات در یک سیکل ، محتوای pattern space را خروجی استاندارد چاپ می کند . پس نتیجه اجرای دستور به این صورت در می آید که یک خط شماره خط و خط دیگر محتوای خط نمایش داده می شود و به همین صورت تا انتهای فایل. برای فهم دقیق مساله به خروجی مثال بالا توجه کنید.
حال مساله کامل را بررسی می کنیم :
# sed '=' data.txt | sed 'N;s/\n/\t/'
بخش اول دستور بالا قبل از pipe همان است که در بالا خروجی آن را دیدیم که این بار خروجی خود را در pipe می ریزد و sed دوم هم ورودی خود را به جای خواندن از فایل اینبار از pipe می خواند. دستور N در sed دوم خط بعدی را می خواند و به pattern space اضافه می کند و دستور s کاراکتر n\ موجود بین دو خط حاضر در pattern space را به کاراکتر t\ یعنی همان tab عوض می کند.
مثال ۴) شماره هر خط غیر خالی را در سمت چپ آن قرار دهید.
# sed '/./ =' data.txt | sed '/./ {N;s/\n/\t/;}'
3 This is line number: #3. line 1 and 2 is empty
4 This is line number: #4
5 This is line number: #5
6 This is line number: #6
7 This is line number: #7
9 This is line number: #9
10 This is line number: #10
13 This is line number: #13 . Note that line number 14 is empty
مثال ۵) تعداد کل خط های یک فایل را برگردانید. (مشابه دستور wc -l)
# sed -n '$ =' data.txt
14
مثال ۶) دستور nl -ba را به صورت دقیق با sed پیاده سازی کنید.
# sed '=' data.txt | sed 'N;s/^/ /;s/ *\(.\{6,\}\)\n/\1\t/'
1
2
3 This is line number: #3. line 1 and 2 is empty
4 This is line number: #4
5 This is line number: #5
6 This is line number: #6
7 This is line number: #7
8
9 This is line number: #9
10 This is line number: #10
11
12
13 This is line number: #13 . Note that line number 14 is empty
14
برای بررسی صحت عملکرد ، خروجی این دستور و نیز خروجی دستور nl -ba را با استفاده از diff و همچنین ls -l با هم مقایسه می کنیم.
# nl -ba data.txt >data.txt.nl
# sed '=' data.txt | sed 'N;s/^/ /;s/ *\(.\{6,\}\)\n/\1\t/' >data.txt.sed
# diff data.txt.nl data.txt.sed
# ls -l data.txt.*
-rw-rw-r-- 1 mohsen mohsen 406 Jan 29 19:32 data.txt.nl
-rw-rw-r-- 1 mohsen mohsen 406 Jan 29 19:32 data.txt.sed
همانطور که مشاهده می کنید دستور diff هیچ گونه اختلافی را نشان نمی دهد و دستور ls هم موید تعداد دقیق کاراکترهای دو فایل است که البته ملاک اصلی یکسان بودن دو فایل دستور diff می باشد و نه برابری تعداد کاراکترهای دو فایل!
مثال ۷) عدد ۱۶۴۸۱۹۵ و یا به طور کلی هر عدد را سه رقم سه رقم با , از هم جدا کنید.
# echo 1648195 | sed ':a s/\(.*[0-9]\)\([0-9]\{3,\}\)/\1,\2/;ta'
1,648,195
دستور t که ابتدای کلمه test می باشد به این معناست که چنانچه آخرین دستور s محتوای pattern space را تغییر داده باشد کنترل را به label داده شده در جلوی t منتقل می کند . در صورت عدم وجود label کنترل به انتهای دستورات sed منتقل می شود.
مثال ۸) کلیه خطوط را در فضای ۷۹ کاراکتری راست چین کنید.
# sed ':a s/^.\{1,78\}$/ &/; ta' data.txt
This is line number: #3. line 1 and 2 is empty
This is line number: #4
This is line number: #5
This is line number: #6
This is line number: #7
This is line number: #9
This is line number: #10
This is line number: #13 . Note that line number 14 is empty
مثال ۹) کلیه خطوط را در فضای ۷۹ کاراکتری وسط چین کنید.
# sed ':a s/^.\{1,77\}$/ & /; ta' data.txt
This is line number: #3. line 1 and 2 is empty
This is line number: #4
This is line number: #5
This is line number: #6
This is line number: #7
This is line number: #9
This is line number: #10
This is line number: #13 . Note that line number 14 is empty
مثال ۱۰) هر خط را با خط بعدی یکی کرده و با یک فاصله از هم جدا کنید.
# sed 'N;s/\n/ /' data.txt
This is line number: #3. line 1 and 2 is empty This is line number: #4
This is line number: #5 This is line number: #6
This is line number: #7
This is line number: #9 This is line number: #10
This is line number: #13 . Note that line number 14 is empty
۹۳/۱۱/۰۹