回覆回應

sed

最後更新: 2015-07-10

介紹

Sed (stream editor)

很詳細的 Documment

(http://www.grymoire.com/Unix/Sed.html)

目錄

  1. 常用 options
  2. Command
  3. 刪除
  4. 取代(substitution)
  5. "|" ":" "@"
  6. print (簡寫 p)
  7. Comments
  8. Print line number with =
  9. Transform with y (1對1的)
  10. Grouping with { and }
  11. Adding(a), Inserting(i), Changing lines
  12. Writing a file with the 'w' command

 


常用 options

# version

sed --version

GNU sed version 4.2.1

-n, --quiet (在 print(p) 時只會 output 中 pattern 的 line)

-e script

-f script-file

修改 File

當沒有 -i 或 -c 時, 只會在 stdout 輸出改過後的內容

# edit files in place (makes backup if extension supplied)

-i[SUFFIX], --in-place=[SUFFIX]

# use copy instead of rename when shuffling files in -i mode.

-c, --copy

# use extended regular expressions in the script.

-r, --regexp-extended


Command

  • s/regexp/replacement/         <--- 用得最多
  • p
  • d
  • w filename
  • y
  • =

實際使用

 

刪除:

 

# 刪除第一行

sed -e '1d' /etc/services

# 刪除第2至第4行

sed '2,4d' test

# 刪除有英文字"awk" 的所有行

sed '/awk/d' filename.txt

# Remove all empty lines:

sed '/^$/d' filename.txt    
sed '/./!d' filename.txt

# delete first n ( ".." 相當於兩個字 ) character

sed -i 's/^..//' > domain.txt

# Remove line "matched" by a regular expression

(by eliminating one containing digital characters (at least 1 digit) located at the end of the line).

sed '/[0-9/][0-9]*$/d' filename.txt

 


取代(substitution)

 

把在 testfile 檔內的每行 is 取代 成 are, 然後 output 到 stdout

sed 's/is/are/g' testfile

有些 sed 版本是不用加 /g 的

/g - Global replacement

直接 replace file

sed -i 's/is/are/g' testfile

# interesting usage insert / remove "#"

# insert "#" at the beginning of a line

sed -i '3 s/^/#/' test.txt

# remove "#" at the beginning of a line

sed -i '3 s/^#//' test.txt

# add string to each line in file

sed -e 's/$/string after each line/' -i filename

 


Regular

 

^    Matches the beginning of the line
$    Matches the end of the line
.     Matches any single character                                                               <--- 真正的"." 是 "\."
*    Will match zero or more occurrences of the previous character
[ ]    Matches all the characters inside the [ ]

expression    Description
/./                Will match any line that contains at least one character
/../               Will match any line that contains at least two characters
/^#/            Will match any line that begins with a '#'
/^$/            Will match all blank lines
/}$/             Will match any lines that ends with '}' (no spaces)
/} *$/          Will match any line ending with '}' followed by zero or more spaces
/[abc]/         Will match any line that contains a lowercase 'a', 'b', or 'c'
/^[abc]/       Will match any line that begins with an 'a', 'b', or 'c'

 

Example:

# duplicate the function of grep with sed:

sed -n -e's/pattern/&/p' <file

P.S.

"&" - corresponds to the pattern found.

"(&)" - \1  through  \9  to  refer to the corresponding matching

 


"|" ":" "@"

 

一切為了簡化

sed 's/\/opt\/omni\/lbin/\/opt\/tools\/bin/g' path.txt

應用:

sed 's|/usr/local/bin|/common/bin|' <old >new

sed 's:/usr/local:/usr:g' mylist.txt

sed 's@/opt/omni/lbin@/opt/tools/bin@g' path.txt

 


print (簡寫 p)

 

$ sed -n -e '/regexp/p' /path/to/my/test/file | more

  • -n 只print 有修改的行

By default, sed prints every line. If it makes a substitution, the new text is printed instead of the old one.

/p - print

找出檔案在 N 與 M之間的內容(N,M 可以是數字式 patten):

usage:

sed -n -e'N,Mp' file.txt

i.e.

sed -n -e'6,7p' test.txt

sed -n '/begin/,/end/p' test.txt

 


Comments

 

Sed comments are lines where the first non-white character is a "#."

On many systems, sed can have only one comment, and it must be the first line of the script.
 


Print line number with =

 

sed -n '/PATTERN/ =' file

 


Transform with y (1對1對換)

 

test.txt

aaaaaa11111
bbbbbb22222
cccccc33333
dddddd44444

sed 'y/bbbbbb/eeeeee/' test.txt

aaaaaa11111
eeeeee22222
cccccc33333
dddddd44444

b 與  e 必須一樣長度
 


Multiple commands for one address(Grouping with { and })

 

Sometimes, you may want to specify multiple commands that will apply to a single address. This comes in especially handy when you are performing lots of 's///' to transform words or syntax in the source file. To perform multiple commands per address, enter your sed commands in a file, and use the '{ }' characters to group commands, as follows:

i.e.

1,20{
    s/[Ll]inux/GNU\/Linux/g
    s/samba/Samba/g
    s/posix/POSIX/g
}

i.e.

1,/^END/{
    s/[Ll]inux/GNU\/Linux/g
    s/samba/Samba/g
    s/posix/POSIX/g
    p
}

This example will apply all the commands between '{ }' to the lines starting at 1 and up to a line beginning with the letters "END", or the end of file if "END" is not found in the source file.

i.e.

#!/bin/sh
# This is a Bourne shell script that removes #-type comments
# between 'begin' and 'end' words.
sed -n '
    /begin/,/end/ {
         s/#.*//
         s/[ ^I]*$//
         /^$/ d
         p
    }
'

 


Adding(a|r), Inserting(i), Changing lines

 

Append a line with 'a'

The "a" command appends a line after the range or pattern. This example will add a line after every line with "WORD"

#!/bin/sh
sed '
/WORD/ a\
Add this line after every line with WORD
'

P.S.

lines are continued by ending the previous line with a "\".

Append a file

r filename             # Append text read from filename.

sed append to end of file

echo "Line" >> /etc/sudoers

Insert a line with 'i'

You can insert a new line before the pattern with the "i" command:

#!/bin/sh
sed '
/WORD/ i\
Add this line before every line with WORD
'

在 match 的行的行頭 insert "#"

Usage:

sed /match/s/^/#/ filename

i.e.

sed /authn_dbd_module/s/^/#/ 00-base.conf

Change a line with 'c'

You can change the current line with a new line.

#!/bin/sh
sed '
/WORD/ c\
Replace the current line with the line
'

i.e.

cat myfile

aaaaaa11111
bbbbbb22222
cccccc33333
dddddd44444

sed '/bbbbbb/c eeeee' myfile

cat myfile

aaaaaa11111
eeeee
cccccc33333
dddddd44444

A "d" command followed by a "a" command won't work, as I discussed earlier.

The "d" command would terminate the current actions. You can combine all three actions using curly braces:

#!/bin/sh
sed '
/WORD/ {
i\
Add this line before
a\
Add this line after
c\
Change the line to this one
}'

 


Writing a file with the 'w' command

 

sed -n 's/^[0-9]*[02468] /&/w even' < file

I used the "&" in the replacement part of the substitution command so that the line would not be changed.

A simpler example is to use the "w" command, which has the same syntax as the "w" flag in the substitute command

 


 

回應

此欄位內容將保密,不會公開顯示出來。