分页: 1 / 1

HP-UX用grep输出满足条件的前几行或后几行

发表于 : 2014年 8月 22日 12:16 星期五
admin
一般HP-UX并没有使用GNU的grep所以无法执行grep -A <#> -B <#> 来显示关键字的前后几行。

有折冲的方法就是使用sed命令

# print only lines which match regular expression (emulates "grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2

# print only lines which do NOT match regexp (emulates "grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax

# print 1 line of context before and after regexp, with line number
# indicating where the regexp occurred (similar to "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

Re: HP-UX用grep输出满足条件的前几行或后几行

发表于 : 2014年 8月 22日 12:17 星期五
admin
参考

Handy one-liners for SED

HANDY ONE-LINERS FOR SED (Unix stream editor) April 25, 1998
compiled by Eric Pement <epement@jpusa.chi.il.us> version 4.5
Latest version of this file is always at <http://www.wollery.demon.co.uk>

FILE SPACING:

# double space a file
sed G

# triple space a file
sed 'G;G'

# undo double-spacing (assumes even-numbered lines are always blank)
sed 'n;d'

NUMBERING:

# number each line of a file (simple left alignment). Using a tab (see
# note on '\t' at end of file) instead of space will preserve margins.
sed = filename | sed 'N;s/\n/\t/'

# number each line of a file (number on left, right-aligned)
sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'

# number each line of file, but only print numbers if line is not blank
sed '/./=' filename | sed '/./N; s/\n/ /'

# count lines (emulates "wc -l")
sed -n '$='

TEXT CONVERSION AND SUBSTITUTION:

# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
sed 's/.$//' # assumes that all lines end with CR/LF
sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//' # sed v1.5 only

# IN DOS ENVIRONMENT: convert Unix newlines (LF) to DOS format
sed 's/$//' # method 1
sed -n p # method 2

# delete leading whitespace (spaces, tabs) from front of each line
# aligns all text flush left
sed 's/^[ \t]*//' # '\t'=tab (see note at end of file)

# delete trailing whitespace (spaces, tabs) from end of each line
sed 's/[ \t]*$//' # '\t'=tab (see note at end of file)

# delete BOTH leading and trailing whitespace from each line
sed 's/^[ \t]*//;s/[ \t]*$//'

# insert 5 blank spaces at beginning of each line (make page offset)
sed 's/^/ /'

# align all text flush right on a 79-column width
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # set at 78 plus 1 space

# center all text in the middle of 79-column width. In method 1,
# spaces at the beginning of the line are significant, and trailing
# spaces are appended at the end of the line. In method 2, spaces at
# the beginning of the line are discarded in centering the line, and
# no trailing spaces appear at the end of lines.
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # method 1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # method 2

# substitute (find & replace) "foo" with "bar" on each line
sed 's/foo/bar/' # replaces only 1st instance in a line
sed 's/foo/bar/4' # replaces only 4th instance in a line
sed 's/foo/bar/g' # replaces ALL instances in a line

# substitute "foo" with "bar" ONLY for lines which contain "baz"
sed '/baz/s/foo/bar/g'

# substitute "foo" with "bar" EXCEPT for lines which contain "baz"
sed '/baz/!s/foo/bar/g'

# reverse order of lines (emulates "tac")
sed '1!G;h;$!d'

# reverse each character on the line (emulates "rev")
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'

# join pairs of lines side-by-side (like "paste")
sed 'N;s/\n/ /'

SELECTIVE PRINTING OF CERTAIN LINES:

# print all but first line of file
sed 1d infile >> outfile

# print first 10 lines of file (emulates behavior of "head")
sed 10q

# print first line of file (emulates "head -1")
sed q

# print last 10 lines of file (emulates "tail")
sed -e :a -e '$q;N;11,$D;ba'

# print last line of file (emulates "tail -1")
sed '$!d'

# print only lines which match regular expression (emulates "grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2

# print only lines which do NOT match regexp (emulates "grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax

# print 1 line of context before and after regexp, with line number
# indicating where the regexp occurred (similar to "grep -A1 -B1")
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h

# grep for AAA and BBB and CCC (in any order)
sed '/AAA/!d; /BBB/!d; /CCC/!d'

# grep for AAA and BBB and CCC (in that order)
sed '/AAA.*BBB.*CCC/!d'

# grep for AAA or BBB or CCC (emulates "egrep")
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

# print paragraph if it contains AAA (blank lines separate paragraphs)
# HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'

# print paragraph if it contains AAA and BBB and CCC (in any order)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'

# print paragraph if it contains AAA or BBB or CCC
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

# print only lines of 65 characters or longer
sed -n '/^.\{65\}/p'

# print only lines of less than 65 characters
sed -n '/^.\{65\}/!p' # method 1, corresponds to above
sed '/^.\{65\}/d' # method 2, simpler syntax

# print section of file from regular expression to end of file
sed -n '/regexp/,$p'

# print section of file based on line numbers (lines 8-12, inclusive)
sed -n '8,12p' # method 1
sed '8,12!d' # method 2

# print line number 52
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p' # case sensitive

SELECTIVE DELETION OF CERTAIN LINES:

# print all of file EXCEPT section between 2 regular expressions
sed '/Iowa/,/Montana/d'

# delete duplicate lines from a sorted file (emulates "uniq"). First
# line in a set of duplicate lines is kept, the rest are deleted
sed '$!N; /^\(.*\)\n\1$/!P; D'

# delete ALL blank lines from a file (same as "grep '.' ")
sed '/^$/d'

# delete all CONSECUTIVE blank lines from file except the first; also
# deletes all blank lines from top and end of file (emulates "cat -s")
sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF
sed '/^$/N;/\n$/D' # method 2, allows 1 blank at top, 0 at EOF

# delete all CONSECUTIVE blank lines from file except the first 2:
sed '/^$/N;/\n$/N;//D'

# delete all leading blank lines at top of file
sed '/./,$!d'

# delete all trailing blank lines at end of file
sed -e :a -e '/^\n*$/N;/\n$/ba'

# delete the last line of the file
sed -e '$d' outputfile

# delete the last line of each paragraph
sed -n '/^$/{p;h;};/./{x;/./p;}'

SPECIAL APPLICATIONS:

# remove nroff overstrikes (char, backspace) from man pages. The 'echo'
# command may need an -e switch if you use Unix System V or bash shell.
sed "s/.`echo \\\b`//g" # double quotes required for Unix environment
sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H
sed 's/.\x08//g' # hex expression for sed v1.5

# get Usenet/e-mail message header
sed '/^$/q' # deletes everything after first blank line

# get Usenet/e-mail message body
sed '1,/^$/d' # deletes everything up to first blank line

# get Subject header, but remove initial "Subject: " portion
sed '/^Subject: */!d; s///;q'

# get return address header
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

# parse out the address proper. Pulls out the e-mail address by itself
# from the 1-line return address header (see preceding script)
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'

# add a leading angle bracket and space to each line (quote a message)
sed 's/^/> /'

# delete leading angle bracket & space from each line (unquote a message)
sed 's/^> //'

# remove most HTML tags (accommodates multiple-line tags)
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'

# extract multi-part uuencoded binaries, removing extraneous header
# info, so that only the uuencoded portion remains. Files passed to
# sed must be passed in the proper order. Version 1 can be entered
# from the command line; version 2 can be made into an executable
# Unix shell script. (Modified from a script by Rahul Dhesi.)
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode # vers. 1
sed '/^end/,/^begin/d' $* | uudecode # vers. 2

# zip up each .TXT file individually, deleting the source file and
# setting the name of each .ZIP file to the basename of the .TXT file
# (under DOS: the "dir /b" switch returns bare filenames in all caps).
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat

TYPICAL USE: Sed takes one or more editing commands and applies all of
them, in sequence, to each line of input. After all the commands have
been applied to the first input line, that line is output and a second
input line is taken for processing, and the cycle repeats. The
preceding examples assume that input comes from the standard input
device (i.e, the console, normally this will be piped input). One or
more filenames can be appended to the command line if the input does
not come from stdin. Output is sent to stdout (the screen). Thus:

cat filename | sed '10q' # uses piped input
sed '10q' filename # same effect, avoids a useless "cat"
sed '10q' filename > newfile # redirects output to disk

For additional syntax instructions, including the way to apply editing
commands from a disk file instead of the command line, consult "sed &
awk, 2nd Edition," by Dale Dougherty and Arnold Robbins (O'Reilly,
1997; http://www.ora.com), "UNIX Text Processing," by Dale Dougherty
and Tim O'Reilly (Hayden Books, 1987) or the tutorials by Mike Arst
distributed in U-SEDIT2.ZIP (many sites). To fully exploit the power
of sed, one must understand "regular expressions." For this, see
"Mastering Regular Expressions" by Jeffrey Friedl (O'Reilly, 1997).
The manual ("man") pages on Unix systems may be helpful (try "man
sed", "man regexp", or the subsection on regular expressions in "man
ed"), but man pages are notoriously difficult. They are not written to
teach sed use or regexps to first-time users, but as a reference text
for those already acquainted with these tools.

QUOTING SYNTAX: The preceding examples use single quotes ('...')
instead of double quotes ("...") to enclose editing commands, since
sed is typically used on a Unix platform. Single quotes prevent the
Unix shell from intrepreting the dollar sign ($) and backquotes
(`...`), which are expanded by the shell if they are enclosed in
double quotes. Users of the "csh" shell and derivatives will also need
to quote the exclamation mark (!) with the backslash (i.e., \!) to
properly run the examples listed above, even within single quotes.
Versions of sed written for DOS invariably require double quotes
("...") instead of single quotes to enclose editing commands.

USE OF '\t' IN SED SCRIPTS: For clarity in documentation, we have used
the expression '\t' to indicate a tab character (0x09) in the scripts.
However, most versions of sed do not recognize the '\t' abbreviation,
so when typing these scripts from the command line, you should press
the TAB key instead. '\t' is supported as a regular expression
metacharacter in awk, perl, and in a few implementations of sed.

VERSIONS OF SED: Versions of sed do differ, and some slight syntax
variation is to be expected. In particular, most do not support the
use of labels (:name) or branch instructions (b,t) within editing
commands, except at the end of those commands. We have used the syntax
which will be portable to most users of sed, even though the popular
GNU versions of sed allow a more succinct syntax. When the reader sees
a fairly long command such as this:

sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d

it is heartening to know that GNU sed will let you reduce it to:

sed '/AAA/b;/BBB/b;/CCC/b;d'

In addition, remember that while many versions of sed accept a command
like "/one/ s/RE1/RE2/", some do NOT allow "/one/! s/RE1/RE2/", which
contains space before the 's'. Omit the space when typing the command.

OPTIMIZING FOR SPEED: If execution speed needs to be increased (due to
large input files or slow processors or hard disks), substitution will
be executed more quickly if the "find" expression is specified before
giving the "s/.../.../" instruction. Thus:

sed 's/foo/bar/g' filename # standard replace command
sed '/foo/ s/foo/bar/g' filename # executes more quickly
sed '/foo/ s//bar/g' filename # shorthand sed syntax

On line selection or deletion in which you only need to output lines
from the first part of the file, a "quit" command (q) in the script
will drastically reduce processing time for large files. Thus:

sed -n '45,50p' filename # print line nos. 45-50 of a file
sed -n '51q;45,50p' filename # same, but executes much faster

If you have any additional scripts to contribute or if you find errors
in this document, please send e-mail to the compiler. Indicate the
version of sed you used, the operating system it was compiled for, and
the nature of the problem. Various scripts in this file were written
or contributed by:

Al Aab <af137@freenet.toronto.on.ca> # "seders" list moderator
Yiorgos Adamopoulos <adamo@softlab.ece.ntua.gr>
Dale Dougherty <dale@songline.com> # author of "sed & awk"
Carlos Duarte <cdua@algos.inesc.pt> # author of "do it with sed"
Eric Pement <epement@jpusa.chi.il.us> # author of this document
S.G.Ravenhall <S.G.Ravenhall@open.ac.uk> # great de-html script
Greg Ubben <gsu@romulus.ncsc.mil> # many contributions & much help

Re: HP-UX用grep输出满足条件的前几行或后几行

发表于 : 2014年 8月 25日 11:34 星期一
admin
参考 ChinaUnix翻译加注sed1line

FILE SPACING:

# double space a file
#使一个文件中每一行都占用两行空间(就是在每一行后边插一行空行)
sed G
###sed 中G命令的解释为append hold space to pattern space.
###就是在当前位置后加一行保留空间中的内容,无任何动作时,保留空间为空行
###所以就double space a file 了,呵呵.

# double space a file which already has blank lines in it. Output file
# should contain no more than one blank line between lines of text.
#假若文件已经含有空白行在其中,使一个文件中每一行占用两行
#空间。输出文件中文本行之间不含有超过一行的空行
sed '/^$/d;G'
###先用sed '/^$/d' 查找并删除空行;然后用 sed G插入空行

# triple space a file
#使一个文件中每一行都占用三行空间(就是在每一行后边插两行空行)
sed 'G;G'
###不用说了吧,重复两次sed G.

# undo double-spacing (assumes even-numbered lines are always blank)
#撤销占用两行空间的操作(假设偶数行都是空白行)
sed 'n;d'
###sed 中命令n的解释为Read the next line of input into the pattern space.
###所以我理解为用sed n 读入下一行并紧接着用sed d 删除,如果隔两行删除一行那么
###用sed 'n,n,d',要是隔100行删除一行呢....什么???!!!你要写100个n???!!!

# insert a blank line above every line which matches "regex"
#在每个含有字符串regex的行上插入一行空白行
sed '/regex/{x;p;x;}'
###sed 中命令x解释为Exchange the contents of the hold and pattern spaces.
###我的理解也就是交换保留空间与模式空间的内容
###sed 中命令p为Print the current pattern space.就是打印模式空间中的内容.
###所以理解为保留空间中开始为空行,模式空间中经过sed '/regex/'查询后为包含
###regex内容的那一行,1)x;交换模式空间和保留空间的内容,此时模式空间中内容
###为空行,保留空间中内容为含有regex内容的行, 2)p;命令打印模式空间内容(
###空行),在原文中含有regex内容的那一行的位置出现两行空行,其中后一行为
###模式空间中的内容,3)x;后交换模式空间和保留空间中的内容,....结果就是在原
###来出现regex的位置前一行加入了一行空行。

# insert a blank line below every line which matches "regex"
# 在每个含有字符串regex的行下插入一行空白行
sed '/regex/G'
###比较简单,查找后在后边加入一空行

# insert a blank line above and below every line which matches "regex"
#在每个含有字符串regex的行上,下各插入一行空白行
sed '/regex/{x;p;x;G;}'
###兄弟两个sed '/regex/G'和sed '/regex/{x;p;x;}'合作的结果.

NUMBERING:

# number each line of a file (simple left alignment) Using a tab (see
# note on '/t' at end of file)instead of space will preserve margins.
#给文件每一行加上数字序号。用TAB制表符替换空间来保留空白(?)
#(在数字序号和文本中间加一TAB制表符)
sed = filename | sed 'N;s//n//t/'
###sed = filename的功能是 Print the current line number.
###但是这个功能是在每一行前面另加一行,并且显示行号,而不是直接在行首加序号
###sed中命令N的解释为Append the next line of input into the pattern space.
###也就是把当前行后一行的内容加在当前行后边.
###sed中命令s/regexp/replacement/解释为Attempt to match regexp against the
###pattern space. If successful, replace that portion matched with
### replacement.大概意思是在模式空间外匹配regexp,如果成功,使用匹配replace
###ment的内容替换regexp.说白了就是查找替换吧./n是换行符,/t是TAB制表符,
###所以整个命令的意思也就出来了.

# number each line of a file (nnumber on left, right-aligned)
#给文件每一行加上数字序号(数字在左边,向右对齐?)
sed = filename | sed 'N; s/^/ /; s/ */(./{6,/}/)/n//1 /'
### 前面不用说了,但是后边......
###s/ */(./{6,/}/)/n//1 /' 这个地方确实不是很明白!

# number each line of file, but only print numbers if line is not blank
#给文件每一行加上数字序号,但是仅当行非空时打印数字
sed '/./=' filename | sed '/./N; s//n/ /'
###sed '/./=' filename的用处是查找除非空行赋予行号,sed '/./N; s//n/ /'查找非
##空行并把后一行附加到当前行,然后用空格替换换行符/n


# count lines (emulates "wc -l")
#统计行数(类似于 "wc -l")
sed -n '$='
#sed中参数n的含义是suppress automatic printing of pattern space,也就是限制
###自动打印模式空间中内容的功能, '$='中$的含义是Match the last line,=前边
###已经说过了,就是打印行号,所以匹配最后一行而且只打印行号不打印内容,就是
###"wc -l"了

TEXT CONVERSION AND SUBSTITUTION:

# IN UNIX ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format
#在UNIX环境下:转换DOS换行符(?)(cR/LF)UNIX格式

sed 's/.$//' # assumes that all lines end with CR/LF
# 假设所有的行都以CR/LF结尾
###可能在DOS中的ASCII码(包括CR/LF)到了UNIX中都成了单字符吧,又因为".$"代表
###每行最后一个字符,所以把它们替换掉就OK了.CR/LF是啥?CR---ASCII Carriage
###Return(ASCII 回车) ,LF----ASCII Linefeed (ASCII换行)

sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
#在bash/tcsh中,按下Ctrl-V然后按 Ctrl-M
###没啥说的,就是查找替换,注意命令中"^M"在输入时一定是按下Ctrl-V然后按 Ctrl-M
###如果输入成ctrl+6键,然后输入一个大写M,什么替换也完成不了啦.

sed 's//x0D$//' # gsed 3.02.80, but top script is easier
# ???
###不是很了解!高手说一下吧!

# IN UNIX ENVIRONMENT: convert Unix newlines (F)to DOS format
#在unix环境中:转换Unix换行符(F)DOS格式
sed "s/$/`echo -e ///r`/" # command line under ksh
             #在ksh下的命令行
sed 's/$'"/`echo ///r`/" # command line under bash
             #在bash下的命令行
sed "s/$/`echo ///r`/" # command line under zsh
#在zsh下的命令行
sed 's/$//r/' # gsed 3.02.80
       # gsed3.02.80版本下的命令行
###以上四个命令是在不同的shell版本下用/r(好象就是ASCII码下的CR)替换行尾

# IN DOS ENVIRONMENT: convert Unix newlines (F)to DOS format
#在DOS环境下转换Unix换行符到DOS格式
sed "s/$//" # method 1
sed -n p # method 2
###这句又不是很了解,本来$就是行尾了,把行尾替换成空,那就变成了DOS格式了吗?
###下边一句也很奇怪,参数-n是suppress automatic printing of pattern space,命
###令p是Print the current pattern space,一正一反就换成DOS格式了?乖乖


# IN DOS ENVIRONMENT: convert DOS newlines (cR/LF)to Unix format
#在Dos环境下:转换DOS换行符为UNIX格式
# Cannot be done with DOS versions of sed. Use "tr" instead.
#用DOS版本的sed不能做到这点,用"tr"代替.
tr -d /r <infile >outfile # GNU tr version 1.22 or higher
             #GNU tr 1.22版本或者更高版本

# delete leading whitespace (spaces, tabs)from front of each line
# aligns all text flush left
#删除每一行开头的空白(空格,TAB)左对齐排列全文.
sed 's/^[ /t]*//' # see note on '/t' at end of file
         # ???
### 又是替换成空,^[ /t]* 的含义为以空格或者TAB键开始的(或者是他们的组合)行.

# delete trailing whitespace (spaces, tabs)from end of each line
#从每一行结尾处删除最后的空格(空格,TAB)
sed 's/[ /t]*$//' # see note on '/t' at end of file
#??
### 跟上边的命令"前呼后拥"呀.

# delete BOTH leading and trailing whitespace from each line
#删除每一行的开头和结尾的空格
sed 's/^[ /t]*//;s/[ /t]*$//'
###两步走.

# insert 5 blank spaces at beginning of each line (ake page offset)
#在每一行开始处插入5个空格(整页偏移)
sed 's/^/ /'
###没啥说的.

# align all text flush right on a 79-column width
#右对齐,按79列宽排列所有文本
sed -e :a -e 's/^./{1,78/}$/ &/;ta' # set at 78 plus 1 space
###这个语句好像很麻烦,不过看懂了还挺有意思.:)
###首先出现了几个新东东1.":" 2."&". 3. "-e " 4."t",解释一下
###1.":" Label for b and t commands.(给b和t命令加注标签)
###2."&" 表示重复整个匹配的规则表达式.
###3. "-e" add the script to the commands to be executed
### 把脚本加到命令里用以执行
###4. t label If a s/// has done a successful substitution since the last
###input line was read and since the last t or T command, then branch to
###label; if label is omitted, branch to end of script.
###如果从读入最后一个输入行并且执行最后一个t或者T命令后,一个s///命令成功替换,
###那么流程分支指向label处,如果label被忽略(就是没有成功替换吧,我想),那么流程
###分支指向脚本结束.
###回过头来看,整个sed命令行是一个循环执行的语句,每一行都要替换(78-当前行的字
###符数)次,所以如果整个文件比较大,或者一行字符数比较少,做这个动作就有点吃力了.
###不信你试试吧,呵呵.

# center all text in the middle of 79-column width. In method 1,
# spaces at the beginning of the line are significant, and trailing
# spaces are appended at the end of the line. In method 2, spaces at
# the beginning of the line are discarded in centering the line, and
# no trailing spaces appear at the end of lines.
#使所有文本居于79列宽的格式中央。在第一种方法中,每一行开头处的空格是
#很重要的,最后的空格被附在行尾。第二种方法中,一行开头的空格在中心对
#齐的行中被丢弃,行尾也没有原来结尾处的空格。
sed -e :a -e 's/^./{1,77/}$/ & /;ta' # method 1
sed -e :a -e 's/^./{1,77/}$/ &/;ta' -e 's//(*/)1//1/' # method 2
###跟上边的差不多,当两边都加空格的时候,效率要高一些

# substitute (ind and replace)"foo" with "bar" on each line
#在每一行中用"bar"替换(找并替换)foo"
sed 's/foo/bar/' # replaces only 1st instance in a line
# 在一行中,仅在第一次出现时替换
sed 's/foo/bar/4' # replaces only 4th instance in a line
#在一行中,仅在第四次出现时替换
sed 's/foo/bar/g' # replaces ALL instances in a line
#在一行中替换所有出现的值
###这三个命令很简单,不多说了.

sed 's//(.*/)foo/(.*foo/)//1bar/2/' # replace the next-to-last case
#替换紧邻最后一个匹配出现的值
###'s///---- The replacement may contain the special character & to refer to that
###portion of the pattern space which matched, and the special escapes /1
### through /9 to refer to the corresponding matching sub-expressions in the regexp.
###就不直接翻译了,大概意思就是replacement处可以包含&代表匹配的模式空间中
###的部分,特殊的/1-/9可以代表regexp中相应的"子表达式",也就是说前面regexp
###可以分为几个子表达式,而后边replacement中可以用/1-/9分别代表它们.这样就
###增加了灵活性,便于修改sed命令.
###把regexp中的/去掉后,就变成(.*)foo(*foo),其中(.*)表示零个或者多个字符,
###这样加上后边的/1bar/2就变成了改变倒数第二个foo,而倒数第一个不变

sed 's//(*/)foo//1bar/' # replace only the last case
#只替换最后一个值
###比上一个简单

# substitute "foo" with "bar" ONLY for lines which contain "baz"
#在每一含有"baz"的行中用"bar"替换(查找并替换)foo"
sed '/baz/s/foo/bar/g'
### /baz/用来查找,后边的用来替换

# substitute "foo" with "bar" EXCEPT for lines which contain "baz"
#在每一不含有"baz"的行中用"bar"替换(找并替换)foo"
sed '/baz/!s/foo/bar/g'
###反其道而行之.

# change "scarlet" or "ruby" or "puce" to "red"
#将"scarlet"或者"ruby"或者"puce"替换成"red"
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' # most seds
#大多数sed可用
###三步走.
gsed 's/scarlet/|ruby/|puce/red/g' # GNU sed only
#仅GNU sed可用


# reverse order of lines (emulates "tac")
#反转文章行的顺序(类似"tac" )
# bug/feature in HHsed v1.5 causes blank lines to be deleted
#???????
sed '1!G;h;$!d' # method 1
###
###首先看第一个命令1!G,这个是啥意思?"!"表示后边的命令对所有没有
###被选定的行发生作用,G呢?获得保留空间(专业名词叫内存缓冲区?)中
###的内容,并追加到当前模式空间的后面.1就是选定第一行.h的含义是拷贝
###模式空间内容到保留空间(内存缓冲区)。那么先看 sed '1!G'什么含义
###执行一下这个命令,假若文件是
### $ cat test.txt
### 1
### 2
### 3
### 4
###那么 sed '1!G' test.txt的结果是
### $ sed '1!G' test.txt
### 1
### 2
###
### 3
###
### 4
###
### $
### 也就是说除了第一行,后边每行都加了空行,这是因为内存缓冲区中默认值
###是空行吧。然后我们加上h,看看发生什么
### $ sed '1!G;h' test.txt
### 1
### 2
### 1
### 3
### 2
### 1
### 4
### 3
### 2
### 1
### $
### 空行没了,咋回事?我是这样理解的,不知道对不对,大家帮助看看:)
###首先要确定,执行到每一行,sed把当前处理的行存在临时的缓冲区内,
###称为模式空间(pattern space).一旦sed完成对模式空间中行的处理,模式
###空间中的行就被送往屏幕.行被处理完成后,就被移出模式空间...
###
###命令执行第一行时,由于匹配了第一行,所以"!G"不起作用,只打印了
###第一行的内容,然后"h"把模版块中的内容也就是第一行的内容拷贝进缓冲区,
###注意此时是用第一行的内容替换空行.模式空间中的内容要打印,所以出现1.
###执行到第二行时,打印第二行内容,而且由于不匹配"1",所以在后边"G"命令起
###作用,获得了缓冲区中的第一行的内容,然后加到当前模式空间中,并打印,出现
###21。然后把模式空间中的内容写入缓冲区,也就是把21写入缓冲区。执行到第三行
###匹配不成功,所以缓冲区的内容应该是第二行的内容加上第一行的内容,追加到模
###式空间的第三行后边:321.然后把321拷贝到缓冲区,...以此类推就出现了上
###面的结果.
###我不知道这么解释对不对,但是当我把命令中的1换成2,3,4后执行,得到了我
###想象的结果。还请高手指点
###加上最后一句"$!d",那就是前面三行的结果删除,保留最后一行。这样就形成了
### tac的效果啦。

sed -n '1!G;h;$p' # method 2
###与上边类似的,不罗嗦!

# reverse each character on the line (emulates "rev")
#反转一行中每个字符的顺序(类似"rev")
sed '//n/!G;s//(./)/(.*/n/)/&/2/1/;//D;s/.//'
###这个命令真是.....
###我是在解释不通,所以按照我的想法来说一下吧,完全是瞎说!
###'//n/!G'是判断本行是否有换行符,如果没有执行G命令
###'s//(./)/(.*/n/)/&/2/1/'命令是在原来行+第二个字符(或者没有)开始到换行符+第一个字符
###//D命令是在模式空间删除第一行,注意执行完成后如果模式空间不为空,继续下一个
###循环执行.//D是有条件的,而D是无条件的。//表示最近使用的pattern
###s/.//命令是删除第一个字符
###假设一行文字是 123/n
###那么执行后模式空间中的内容应该按下边的顺序变化
### 123/n
### 123/n23/n1
### 23/n1
### 23/n13/n21
### 13/n21
### 3/n21
### 3/n21/n321
### /n321
### 321
### 我的疑问就是,为什么第一次没有执行s/.//?!如果执行了,那么就得不到结果了啊!


#反转一行中每个字符的顺序(类似"rev")
sed '//n/!G;s//(./)/(.*/n/)/&/2/1/;//D;s/.//'
###假设一行文字是 123
###那么执行后模式空间中的内容应该按下边的顺序变化
执行//n/!G;得
123/n
然后s//(./)/(.*/n/)/&/2/1/;

123/n23/n1
执行//D
23/n1
因为是D命令所以从头循环
模式空间有/n
所以//n/!G;中G不执行
再来s...
23/n3/n21
再D
3/n21
循环,G不执行
再来s...
3/n/n321
再D
/n321
循环
G和s和D都不执行
执行最后的s/.//
321
# join pairs of lines side-by-side (like "paste")
#把两行合为一行(类似于"paste")
sed '$!N;s//n/ /'
###这个命令改成 sed 'N;s//n/ /'一样可以达到目的,不知前面
###的$!有什么用处...

# if a line ends with a backslash, append the next line to it
#如果一行以"/"结束,把下一行加在此行上
sed -e :a -e '///$/N; s////n//; ta'
###循环操作,两次替换。

# if a line begins with an equal sign, append it to the previous line
# and replace the "=" with a single space
#如果一等号开始某一行,把这一行加到前一行后边,并且用一个空格替换等号
sed -e :a -e '$!N;s//n=/ /;ta' -e 'P;D'
###和上边差不多,要注意两个新的命令:
### P命令--Print up to the first embedded newline of the current
###pattern space.打印当前模式空间中第一行。
###D命令--Delete up to the first embedded newline in
### the pattern space. Start next cycle, but skip reading from
###the input if there is still data in the pattern space.
###删除当前模式空间中第一行。开始新的循环,但是如果在模式空间中仍然
###有数据,那么跳过读取输入。

# add commas to numeric strings, changing "1234567" to "1,234,567"
#给数字串加逗号,把"1234567"变为"1,234,567"
gsed ':a;s//B[0-9]/{3/}/>/,&/;ta' # GNU sed
sed -e :a -e 's//(.*[0-9]/)/([0-9]/{3/}/)//1,/2/;ta' # other seds
###(.*[0-9])表示零个或者多个字符(可能包含数字)+一个数字,而
###([0-9]{3})表示三个数字,然后不停的替换,直到条件不成立,也就是没有
###四个以上连续的数字出现就停止了.

# add commas to numbers with decimal points and minus signs (NU sed)
#给带有小数点和负号的数字的数字加上逗号
gsed ':a;s//(^/|[^0-9.]/)/([0-9]/+/)/([0-9]/{3/}/)//1/2,/3/g;ta'
###没有gsed,不解释了

# add a blank line every 5 lines (after lines 5, 10, 15, 20, etc.)
#每五行后加一空行
gsed '0~5G' # GNU sed only
sed 'n;n;n;n;G;' # other seds
###一大早就说过了的...

SELECTIVE PRINTING OF CERTAIN LINES:

# print first 10 lines of file (emulates behavior of "head")
#打印一个文件的前10行(模仿动作"head")
sed 10q

# print first line of file (emulates "head -1")
#打印一个文件的第一行(仿"head -1")
sed q
### q命令的解释Immediately quit the sed script without processing
###any more input, except that if auto-print is not disabled the
###current pattern space will be printed.
### 所以上边两个命令都清楚了,执行到第10行退出就打印前10行,执行第一行
###就退出就打印第一行

# print the last 10 lines of a file (emulates "tail")
#打印一个文件的后10行(仿"tail")
sed -e :a -e '$q;N;11,$D;ba'
###Label b : Branch to label; if label is omitted, branch to end of script.
###命令D 删除模式空间内第一个 newline 字母 /n 前的资料。
###命令N 把输入的下一行添加到模式空间中。
### b label:分支到脚本中带有标号的地方,如果标号不存就分支到脚本的末尾
###


试着注一下,不知道对不对

如果我们只看sed -e :a -e '$q;N;ba'
这个循环不停的读入下 一行直到结尾,这样整个文本就形成一个由/n分割的链

现在加上11,$D
sed -e :a -e '$q;N;11,$D;ba'
如果文本不超过10行
模式空间将保留整个文本打印出来
如果文本大于10行
从第11行开始,在下一行加入到链中后,模式空间第一个由/n分割的记录将被删除,这样看起来就是链头被链尾挤出整个链,总是保持10个链环,循环结束后,链中保存的就是文件的后10行,最后印出结果
:em16:

# print the last 2 lines of a file (emulates "tail -2")
#打印一个文件的最后两行(仿"tail -2")
sed '$!N;$!D'
### 开始看不太懂,抄了CU精华一段
###sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模
###式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行
###附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。
###不知道是这段话说得有些含糊,还是我理解得有偏差,总觉得D命令解释成
###"将模式空间的内容删除了"有些让人糊涂.
###而我是这样理解的,不知道对不对.首先说D命令是 Delete up to the first
###embedded newline in the pattern space.也就是说D命令是删除模式空间中
###第一个换行符之前的内容,也就是删除第一行.然后D命令的解释还有一句,我认为
###这句很重要: Start next cycle, but skip reading from the input if there
### is still data in the pattern space.开始下一个循环,但是如果模式空间中有
###数据,则跳过从输入中读取数据.
###具体怎么工作呢? 假设文件为
### $ cat test.txt
### 1
### 2
### 3
### 4
### 5
### 那么当执行第一行时,$!N把第二行加入到模式空间中第一行后边,然后$!D把第一行
###内容删除,模式空间中只剩下第二行的内容.注意,此时由于D命令开始下一个循环,
###所以不打印模式空间中的内容! (这个地方也是我想了半天才这么解释的,我也知道
###很可能不对,欢迎拍砖,呵呵)由于D命令要求模式空间中有数据的话就跳过读取下一行,
###所以继续下一个循环又到了$!N,此时读入第三行加到第二行后边,....以此类推。
###执行到读入第5行附加在第四行后边,然后由于$!D得不到执行,所以第4行和第5行
###都被保留,命令结束,打印模式空间...

# print the last line of a file (emulates "tail -1")
#打印一个文件的最后一行(仿"tail -1")
sed '$!d' # method 1
sed -n '$p' # method 2
###哈哈,终于看懂了一个,你也看懂了吧 :)


# print only lines which match regular expression (emulates "grep")
#只打印匹配的一定字符的行(仿"grep")
sed -n '/regexp/p' # method 1
sed '/regexp/!d' # method 2
###明白参数-n和命令p和d就明白这两个命令.

# print only lines which do NOT match regexp (emulates "grep -v")
#只打印于一定字符不匹配的行(效"grep -v")
sed -n '/regexp/!p' # method 1, corresponds to above
sed '/regexp/d' # method 2, simpler syntax
###和上边相反,正如注释所说.

# print the line immediately before a regexp, but not the line
# containing the regexp
#打印包含"regexp"那一行的上一行,但是不打印包含"regexp"的行.
sed -n '/regexp/{g;1!p;};h'
###在命令执行到包含"regexp"那一行的上一行时,模式空间中这行的内容被
###拷贝到保留空间中.执行到包含"regexp"那一行时就打印它了.

# print the line immediately after a regexp, but not the line
# containing the regexp
#打印在"regexp"之后紧跟那一行,但是除去包含"regexp"的行.
sed -n '/regexp/{n;p;}'
###与上边类似,比上边简单.

# print 1 line of context before and after regexp, with line number
# indicating where the regexp occurred (imilar to "grep -A1 -B1")
#在"regexp"前后打印一行上下文,使其行号指示"regexp"在哪里出现(
#grep -A1 -B1相似)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
###看上去好像挺复杂,其实倒是不难解释.
###假设文档是这样
###$ cat test.txt
### 1 abc
### 2 cde
### 3 regexp
### 4 fgh
### 5 xyz
###命令执行到regexp前一行,引号里边的命令不执行,只执行h命令得到结果
### command parttern space holdspace output
### 执行到前一行 2cde 2cde
### 执行到regexp行 "=" 3regexp 3
### "x" 2cde 3regexp
### "1!p" 2cde 3regexp 2cde
### "g" 3regexp 3regexp
### "$N" 3regexp ; 4fgh 3regexp
### "p" 3regexp ; 4fgh 3regexp 3regexp
### 4fgh
### "D" 4fgh 3regexp
### "h" 4fgh 4fgh
###
### 看一下最右边的输出结果,还不错吧!

# grep for AAA and BBB and CCC (n any order)
#查找"AAA"和"BBB"和"CCC".(任意顺序)
sed '/AAA/!d; /BBB/!d; /CCC/!d'

# grep for AAA and BBB and CCC (n that order)
# 查找"AAA"和"BBB"和"CCC".(一定顺序)
sed '/AAA.*BBB.*CCC/!d'

# grep for AAA or BBB or CCC (emulates "egrep")
#查找"AAA"或"BBB"或"CCC".(任意顺序)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # most seds
gsed '/AAA/|BBB/|CCC/!d' # GNU sed only
###上边三个没什么说的,就是查找功能呗.


# print paragraph if it contains AAA (blank lines separate paragraphs)
# HHsed v1.5 must insert a 'G;' after 'x;' in the next 3 scripts below
#如果某段包含"AAA",则打印这一段。(空行用来分隔段落)
#HHsed v1.5必须在'x;'之后插入一个'G;'
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
###前边一部分命令用保留空间来存储整个段落内容,后边一个命令用来查找

# print paragraph if it contains AAA and BBB and CCC (n any order)
#如果某段包含"AAA"和"BBB"和"CCC",则打印这一段
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
###同上

# print paragraph if it contains AAA or BBB or CCC
# 如果某段包含"AAA"或"BBB"或"CCC",则打印这一段
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA/|BBB/|CCC/b;d' # GNU sed only
###同上

# print only lines of 65 characters or longer
#仅打印长于65个字符的行
sed -n '/^./{65/}/p'
###这也没什么好说的,正则表达式的运用.

# print only lines of less than 65 characters
#仅打印少于65个字符的行
sed -n '/^./{65/}/!p' # method 1, corresponds to above
sed '/^./{65/}/d' # method 2, simpler syntax
###又没啥吧

# print section of file from regular expression to end of file
#打印从字符"regexp"开始到文件结束的部分
sed -n '/regexp/,$p'
###还没啥,注意","的作用是选择行的范围,从包含regexp的行到最后一行

# print section of file based on line numbers (ines 8-12, inclusive)
#根据行号来打印文件的一部分(-12行,包括在内)
sed -n '8,12p' # method 1
sed '8,12!d' # method 2

# print line number 52
#打印第52行
sed -n '52p' # method 1
sed '52!d' # method 2
sed '52q;d' # method 3, efficient on large files
###仅注意第三种方法效率比较高就行了

# beginning at line 3, print every 7th line
#从第三行开始,每7行打印一行
gsed -n '3~7p' # GNU sed only
sed -n '3,${p;n;n;n;n;n;n;}' # other seds
###好像很容易理解了吧

# print section of file between two regular expressions (nclusive)
#打印文件中指定字符之间的部分(含字符在内)
sed -n '/Iowa/,/Montana/p' # case sensitive
###现在简单了吧.:)

SELECTIVE DELETION OF CERTAIN LINES:

# print all of file EXCEPT section between 2 regular expressions
#打印除指定字符之间部分之外的全文
sed '/Iowa/,/Montana/d'
###与上边相似的简单

# delete duplicate, consecutive lines from a file (emulates "uniq")
# First line in a set of duplicate lines is kept, rest are deleted.
#删除文件中重复的连续的行(似于"uniq"命令)
#重复行中第一行保留,其他删除
sed '$!N; /^/(.*/)/n/1$/!P; D'  
###如果不是最后一行,就把下一行附加在模式空间,然后进行查找操作
###"^"和"$"中间的内容如果有重复就匹配成功.如果匹配不成功就用P打印
###第一行. 然后删除第一行.

# delete duplicate, nonconsecutive lines from a file. Beware not to
# overflow the buffer size of the hold space, or else use GNU sed.
#删除文件中重复的,但不连续的行。注意不要溢出保留空间的缓冲器的大小,
#否则使用GNU sed.
sed -n 'G; s//n/&&/; /^/([ -~]*/n/).*/n/1/d; s//n//; h; P'
###在我的linux环境执行不了,出错是sed: -e expression #1, char 34:
###Invalid range end.是不是所谓的溢出保留空间的大小了呢?我也不得而知.
###大家补充吧.!!?????????????????

# delete the first 10 lines of a file
#删除一个文件中前10行
sed '1,10d'
# delete the last line of a file
#删除一个文件中最后1行
sed '$d'
###与上边一个都是查找删除

# delete the last 2 lines of a file
#删除一个文件中最后2行
sed 'N;$!P;$!D;$d'
###如果理解了sed '$!N;$!D'是如何工作的,这句话也不在话下吧!

# delete the last 10 lines of a file
#删除一个文件中后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2
###和打印后10行相似.什么?打印后10那个没看懂? /shakehand :)
###?????????????????

# delete every 8th line
# 每8行删除1行
gsed '0~8d' # GNU sed only
sed 'n;n;n;n;n;n;n;d;' # other seds
###没说的!

# delete ALL blank lines from a file (ame as "grep '.' ")
#删除文件所有空白行(似于"grep '.' ")
sed '/^$/d' # method 1
sed '/./!d' # method 2
###这两句就是告诉我们1.无内容的删除,2.有内容的保留 : )

# delete all CONSECUTIVE blank lines from file except the first; also
# deletes all blank lines from top and end of file (emulates "cat -s")
#删除文件中除一行空白行之外的所有连续空白行,也同时删除所有从头到尾的所
#有空白行(似于"cat -s")
sed '/./,/^$/!d' # method 1, allows 0 blanks at top, 1 at EOF
#方法1不允许文件顶部有空行,文件尾部可以
sed '/^$/N;//n$/D' # method 2, allows 1 blank at top, 0 at EOF
#方法2不允许文件尾部有空行,文件顶部可以
###两个先选择,后删除命令.不多说了.

# delete all CONSECUTIVE blank lines from file except the first 2:
#删除文件中连续空行中除前两行空白行之外的所有空白行
sed '/^$/N;//n$/N;//D'
###跟上边的命令相似,多了一步而已.

# delete all leading blank lines at top of file
#删除文件开头部分中的所有空白行
sed '/./,$!d'
###从有字符开始的行直到最后一行保留,其他删除.

# delete all trailing blank lines at end of file
#删除文件结尾部分中的所有空白行
sed -e :a -e '/^/n*$/{$d;N;ba' -e '}' # works on all seds
sed -e :a -e '/^/n*$/N;//n$/ba' # ditto, except for gsed 3.02*
###不行了要死了,还是高手说吧,我再看下去会疯的!
###?????????????????????????????

# delete the last line of each paragraph
#删除每个段落中最后1行
sed -n '/^$/{p;h;};/./{x;/./p;}'
###应该是假设段落间用空行分隔
###命令执行时,如果不是空行那么交换模式空间和保留空间,如果交换后
###模式空间不为空,则打印模式空间中内容;如果是空行,那么打印模式空间
###间中的内容,也就是打印空行...以此类推,出现结果.

###终于完了,下边的特殊应用没有加注,随便翻译了一下,可能不够准确,大家参考一下吧. :em11:

SPECIAL APPLICATIONS:

# remove nroff overstrikes (char, backspace)from man pages. The 'echo'
# command may need an -e switch if you use Unix System V or bash shell.
# 从man page页里删除所有overstrikes(字符,backspace).如果使用unix系统v
#或者bash shell,echo命令可能需要-e参数.
sed "s/.`echo ///b`//g" # double quotes required for Unix environment
#unix环境下需要双引号
sed 's/.^H//g' # in bash/tcsh, press Ctrl-V and then Ctrl-H
#在bash/tcsh中,按Ctrl-V然后按Ctrl-H
sed 's/./x08//g' # hex expression for sed v1.5
#sed v1.5中的hex表达式

# get Usenet/e-mail message header
# 获得新闻组/e-mail信息的标题部分
sed '/^$/q' # deletes everything after first blank line

# get Usenet/e-mail message body
#获得新闻组/e-mail信息的主体部分
sed '1,/^$/d' # deletes everything up to first blank line

# get Subject header, but remove initial "Subject: " portion
#获得题目的标题,但是删去开始的"Subject: "部分
sed '/^Subject: */!d; s///;q'

# get return address header
#获得返回的地址标题()
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'

# parse out the address proper. Pulls out the e-mail address by itself
# from the 1-line return address header (ee preceding script)
#正确解析地址。把email地址从一行中单独提出来并返回地址头()
sed 's/ *(*)/; s/>.*//; s/.*[:<] *//'

# add a leading angle bracket and space to each line (uote a message)
#给每行增加的尖括号和空格()信息被引用)
#sed 's/^/> /'

# delete leading angle bracket & space from each line (nquote a message)
#删除每行的尖括号和空格()信息不被引用)
sed 's/^> //'

# remove most HTML tags (ccommodates multiple-line tags)
#删去大部分HTML标签(供多行标签))
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'

# extract multi-part un(?)encoded binaries, removing extraneous header
# info, so that only the uuencoded portion remains. Files passed to
# sed must be passed in the proper order. Version 1 can be entered
# from the command line; version 2 can be made into an executable
# Unix shell script. (odified from a script by Rahul Dhesi.)
#抽取多部分未编码的二进制字节,删除无关的头信息,使得只保留未编码的部分.
#文件传送给sed必须保持正确的顺序。第一版本可以用于命令行的执行,第二版本
#可以制作成一个可执行的unix shell脚本
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode # vers. 1
sed '/^end/,/^begin/d' "$@" | uudecode # vers. 2

# zip up each .TXT file individually, deleting the source file and
# setting the name of each .ZIP file to the basename of the .TXT file
# (under DOS: the "dir /b" switch returns bare filenames in all caps)
#独立的压缩每个txt文件,删除原文件并且根绝原文本文件设置每个zip文件名。
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^/(*/).TXT/pkzip -mo /1 /1.TXT/" >>zipup.bat