??xml version="1.0" encoding="utf-8" standalone="yes"?> q是1.txt的内?/p> 再看执行q两条命令的区别?/p> L “行首” ?#8220;@”的首字母@ 特定字符串的行前插入新行 特定字符串的行后插入新行 特定字符串的删除 在用sedҎ志或者其它文本进行parse的过E当中,有时候我们需要引用外部变量的| 如果替换的变量内容中含有/W号则会提示如下错误Q如 # 上面例子引用了一个环境变?RANDOM的?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> # 上面的例子用了旧式的命令替换,也可以采用新式的命o替换ҎQ如?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> # 下面例子取用当前日期作ؓl果的一部分Q如?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> 2.sed命o使用双引L情况下直接`shell command`或?(shell command)引用命o执行的结?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> cM的,双引L情况Q如?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> # 使用环境变量$RANDOM以及旧式命o替换的例?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /> [root@www ~]# sed [-nefr] [动作] 选项与参敎ͼ -n Q用安?silent)模式。在一?sed 的用法中Q所有来?STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经qsed Ҏ处理的那一?或者动?才会被列出来?-e Q直接在命o列模式上q行 sed 的动作编辑; -f Q直接将 sed 的动作写在一个文件内Q?-f filename 则可以运?filename 内的 sed 动作Q?-r Q?span style="margin: 0px; padding: 0px; color: #0000ff; line-height: 1.5 !important;">sed 的动作支持的是g伸型正规表示法的语法?默认是基正规表示法语? -i Q直接修改读取的文g内容Q而不是输出到l端? 动作说明Q?[n1[,n2]]function n1, n2 Q不见得会存在,一般代表『选择q行动作的行数』,举例来说Q如果我的动作是需要在 10 ?20 行之间进行的Q则?10,20[动作行ؓ] ? functionQ?a Q新增, a 的后面可以接字串Q而这些字串会在新的一行出?目前的下一??c Q取代, c 的后面可以接字串Q这些字串可以取?n1,n2 之间的行Q?d Q删除,因ؓ是删除啊Q所?d 后面通常不接M咚咚Q?i Q插入, i 的后面可以接字串Q而这些字串会在新的一行出?目前的上一?Q?p Q列华ͼ亦即某个选择的数据印出。通常 p 会与参数 sed -n 一赯行~ s Q取代,可以直接q行取代的工作哩Q通常q个 s 的动作可以搭配正规表C法Q例?1,20s/old/new/g 是啦!
sed -i 是直接Ҏ本文件进行操作的sed -i 's/原字W串/新字W串/' /home/1.txt sed -i 's/原字W串/新字W串/g' /home/1.txt
q两条命令的区别是Q看CZ?/p>#cat 1.txt d ddd #ff
sed -i 's/d/7523/' /home/1.txt 执行l果 7523 7523dd #ff sed -i 's/d/7523/g' /home/1.txt 执行l果 7523 752375237523 #ff
sed -i 's/^@//' file
sed -i '/特定字符?i 新行字符?/span>' file
sed -i '/特定字符?a 新行字符?/span>' file
sed -i '/字符?d' file
]]>
或者获取一个shell命o执行的结果,以便辑ֈ更加可观的输出结果。这里介l如何做到?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
sed中用变量替?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
1.sed命o使用双引L情况下,使用$var直接引用
$ echo|sed "s/^/$RANDOM.rmvb_/g"
29328.rmvb_
查找当前目录下的目录文gq将相对路径替换为绝对\?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />find . -type f | sed -n "s/\./$PWD/p"
sed: -e expression #1, char 19: unknown option to `s'
从语法上看,没有M问题Q但׃变量中包含有“/”作ؓ分隔W,q会和sed的替换操作的分隔W?#8220;/”引vhQ所以,只要不?#8220;/”做分隔符可以解册个问题,如果使用“%”而不?#8220;/”来作为sed的替换操作的分隔W,׃会出错。其实???作ؓ分隔W也是可以的Q只要不会与替换中有相同的而且不是元字W的ҎW号都是可以的;使用时可以根据情늁z选择?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />find . -type f | sed -n "s%\.%$PWD%p"
find . -type f | sed -n "s#\.#$PWD#p"
2.sed命o使用单引L情况下,使用'"$var"'引用
cMQ我们可以看?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
$ echo|sed 's/^/'"$RANDOM"'.rmvb_/g'
31338.rmvb_
sed中执行外部命?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
1.sed命o使用单引L情况下?`shell command`'或?$(shell command)'引用命o执行的结?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
q是以上面案例分析,例子如下
$ echo|sed 's/^/'`echo $RANDOM`'.rmvb_/g'
8063.rmvb_
$ echo|sed 's/^/'$(echo $RANDOM)'.rmvb_/g'
18554.rmvb_
$ echo|sed 's/^/'$(date +"%Y%m%d")'.rmvb_/g'
20120108.rmvb_
$ echo|sed "s/^/$(date +"%Y%m%d").rmvb_/g"
20120108.rmvb_
$ echo|sed "s/^/`echo $RANDOM`.rmvb_/g"
4988.rmvb_
ȝ
在sed语句里面Q变量替换或者执行shell命oQ双引号比单引号绕一些弯?/p>
[root@~]# diff -urNa dir1 dir2
-a Treat all files as text and compare them line-by-line, even if they do not seem to be text.
-N, --new-file
In directory comparison, if a file is found in only one directory, treat it as present but empty in the other directory.
-r When comparing directories, recursively compare any subdirectories found.
-u Use the unified output format.
比较文g夹diffQ也可以比较文gMD5列表。下面命令可以获取文件夹中文件md5列表
find /home/ -type f -not \( -name '.*' \) -exec md5sum {} \;
说明Q?1) /home/文g目录
(2) -type f 文gcd为普通文?/p>
(3) -not \( -name '.*' \) qo掉隐藏文件。可以过滤掉不需要考虑的文?/p>
(4) -exec md5sum {} \; Ҏ个文件执行md5sum命o
用tar命o压羃后,比较文g的MD5是不行的。tar压羃会带上文件的旉
sed -i '88 r b.file' a.file #在a.txt的第88行插入文件b.txt awk '1;NR==88{system("cat b.file")}' a.file > a.file
sed -i '/regex/ r b.txt' a.txt # regex是正则表辑ּ awk '/target/{system("cat b.file")}' a.file > c.file
原文Ӟ
[root@xiaowu shell]# cat -n file 1 aaaa 2 bbbb 3 cccc 4 dddd
现在要在W二行即“bbbb”行的下面d一行,内容?#8220;xiaowu”
[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file aaaa bbbb xiaowu cccc dddd
如果要加两行“xiaowu”可以用一下语句,注意?#8220;\n”换行
[root@xiaowu shell]# sed '/bbbb/a\xiaowu\nxiaowu' file aaaa bbbb xiaowu xiaowu cccc dddd
如果要在W二行即“bbbb”行的上添加一行,内容?#8220;xiaowu”Q可以把参数“a”换成“i”
[root@xiaowu shell]# sed '/b/i\xiaowu' file aaaa xiaowu bbbb cccc dddd
以上文g中只有一行匹配,如果文g中有两行或者多行匹配,l果有是如何呢?
[root@xiaowu shell]# cat -n file 1 aaaa 2 bbbb 3 cccc 4 bbbb 5 dddd
[root@xiaowu shell]# sed '/bbbb/a\xiaowu' file aaaa bbbb xiaowu cccc bbbb xiaowu dddd
q果可知,每个匚w行的下一行都会被d“xiaowu”
那么如果指向在第二个“bbbb”的下一行添加内?#8220;xiaowu”Q该如何操作呢?
可以考虑先获取第二个“bbbb”行的行号Q然后根据行号在此行的下一行添?#8220;xiaowu”
获取W二?#8220;bbbb”行的行号的方法:
Ҏ一Q?/p>
[root@xiaowu shell]# cat -n file |grep b |awk '{print $1}'|sed -n "2"p 4
Ҏ二:
[root@xiaowu shell]# sed -n '/bbbb/=' file |sed -n "2"p 4
q果可知第二个“bbbb”行的行号?Q然后再在第四行的前或后d相应的内?
[root@xiaowu shell]# sed -e '4a\xiaowu' file aaaa bbbb cccc bbbb xiaowu dddd
[root@xiaowu shell]# sed -e '4a\xiaowu\nxiaowu' file aaaa bbbb cccc bbbb xiaowu xiaowu dddd
向指定行的末添加指定内容,比如?#8220;ccccc”行的行尾介绍“ eeeee”
[root@xiaowu shell]# cat file aaaaa bbbbb ccccc ddddd [root@xiaowu shell]# sed 's/cc.*/& eeeee/g' file aaaaa bbbbb ccccc eeeee ddddd
有两个特点:
1Q?r参数
2Q在目录后面使用"."?br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />
q样的话可以把/opt/merkle 目录和子目录里面的文件全部下载到本地了?/span>
if [ $STATUS == "OK" ]; then
echo "OK"
fi
在运行时出现?#8220; [: =: unary operator expected” 的错误,׃直找不到原因Q尝试了删除{号两侧的空格和括号里的I格都不用。最?a target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">baidu了一下,才找到原因,在条件表辑ּ外再d一?#8220;[]”Q就不会出错了,如下Q?/span>
if [[ $STATUS = "OK" ]]; then
echo "OK"
fi
I其原因Q是因ؓ如果变量STATUSgؓI,那么条g表达?/span>成?[ = "OK"] Q显?[ ?"OK" 不相{ƈ且缺了 [ W号Q所以报了这L错误。当然不L出错Q如果变量STATUSg为空Q程序就正常了,所以这L错误q是很隐蔽的?/span>
或者,用下面的Ҏ也能避免q种错误Q?/span>
if [ "$STATUS"x == "OK"x ]; then
echo
"OK"
fi?/span>
当然Qx也可以是其他字符。顺便提一点,shell中有没有双引号在很多情况下是一致的?/span>
转自Q?a rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #336699; text-decoration: none; cursor: pointer; word-wrap: break-word;">http://hi.baidu.com/vishare/blog/item/bd8ab9ee289753252cf53417.html
Bash中还可以使用数组变量,其赋值有两种:
(1) name = (value1 ... valuen) 此时下标?开?br>(2) name[index] = value
数组下标的范围没有Q何限?同时也不必用连l的分量.
echo ${arrDest[$i]}
let i++
done
=======================CZQ?for循环===============================
arrSource=("/home/800hr/htdocs/login_jump.php")
arrDest=(ithr elehr buildhr bankhr healthr ctvhr chenhr mechr clothr cneduhr 56hr tourhr foodhr greenhr cnlawhr waimaohr)
for outer in ${arrSource[*]}
#${arrSource[*]} 是数l中的所有元?/span>do
for inner in ${arrDest[*]}
do
echo "ln -s $outer /home/${inner}/campus/"
done
done
1?span>
处理多行模式I间Q?/span>N?/span>D?/span>PQ?/span>2?span> 采用保持I间来保存模式空间的内容q他们可用于后l的命oQ?/span>H?/span>h?/span>G?/span>g?/span>xQ?/span>
3?span> 1?nbsp;?/span>sed后面带有一个以上的命oӞ它的处理序是这LQ?/span>
一ơ读入一行到模式I间Q然后将所有的命o应用于该行;而不是一ơ将一个命令作用与所有行Q?/span>
2?nbsp;当某个条件后面有{}Ӟ{}里面的命令依ơ作用于满该条件的行;
3?nbsp;h/H/g/G命o操作~冲区时Q都会在目的~冲区后加一个换行(即该缓冲区无内容)Q然后复制或q加源缓冲区内容在该换行W之后;
4?nbsp;没有使用-n参数Ӟ当一行执行完所有命令后Q?/span>sed会默认打印最l模式空间中的内容;
如果使用-n参数Q只有应用了p/P命o的模式空间内Ҏ会被打印出来?/span>
本文 “licong” 博客Q请务必保留此出?a >http://licong.blog.51cto.com/542131/204226
$^[[A^[[A^[[A
按删除键Q出来的是这个:
$ ^H^H^H^H^H^H^H
只能?Ctrl+BackSpace 才能删除光标左边的内?..用的那个不习惯啊~~~Q!Q?- -b
后来问到 Wells Q原来只需要做一个小的讑֮Q在Console中启用:
$set -o emasc
原因后来上网查了一下,暂且引用一下《FreeBSD使用大全》中的一D内容:
-----------------------------------------------------------------------------------------------
配置用戶shell
事實上sh與cshQƈ不是普通用戶的最佳選擇,因為這兩個shell在易用性方面做的不夠好Q例如命令行R?輯功能不弗不能利用熱鍵重復執行命令等。較新的shellQ如bash和tcsh都具有這些方便用戶使用的功能,?必須安裝了這些shellE序之后Q才能更Ҏ通用戶的shella置以用這些shellE序。更改用戶的shell 可以使用pw、vipw或chsh?/p>
這兩個shell分別늅sh和csh的風|因此喜好csh風格的可以選擇tcshQ而喜歡sh風格的選?bash。除了這兩Eshell之外Q還有ksh、zsh{shell可供選擇。如果對兩種shell沒有偏好Q可?選擇bashQ它是一個GNU軟gQ比標准sh功能強大的多?/p>
使用了這兩些增強型shell之后Q用戶就可以使用shell提供的命令行R輯功能。按照習慣的不同Q可以選 擇vi風格的編輯方式或emacs風格的方式,~省為emacs方式Q這種方式使用方向鍵來回溯埯過的命oQƈ進行 修改Q而vi風格使用字母命o作編輯鍵Q例如用h、j、k、l四個鍵來移動光標,vi風格的好處是不用基本鍵盤之 外的控制鍵,因而可以適用于Mi端a備Qƈ且進行R輯時手不需離開基本늛Q熟R操作之后最為快捗emacs風格 比vvi風格更適合從個ha算轉向Unix的用者的慣。bash, ksh ,zsh下用下面的命o在emacs 風格和vi風格切換Q?/p>
bash$ set -o emacs
bash$ set -o vi
tcsh中用不同的命oQ?/p>
% bind emacs
% bind vi
還可以為常用的命令設|別名,化用戶輸入Q例如:
bash$ alias ec=”echo This is a alias”
bash$ ec
This is a alias
shell用于方便用戶操作的另一項能力是自動補全命o或文件名的功能,因為FreeBSD下的文g名可能很 P它們全部入比較麻煩。事實上可以輸入部分名字Q然后按Tab鍵(在vi風格下是連續兩次按Esc鍵)Qshell 自動補全文件名的剩余部分。如果已E入的這部分名字不能確定具體的命o或文Ӟ那么shell只將能確定的?分補上,然后韉K通知使用者繼U入以明確具體的文件?/p>
事實上即使在基本的sh或csh下,也可以?“*” {特D字W,用模式匹配的方式來簡化入?/p>
bash$ cd /usr/loca*
bash$ pwd
/usr/local
Unix中的多數E序都具備模式匹配的處理能力Q而shell的模式匹配功能最為常用。shell可以使用?些特D模式來配置多個文Ӟ達到化操作的目的。如果要熟練掌握UnixQ必須掌握模式匹配?/p>
當試圖在bash下入字的時候,除了必須a置i端屬性能接受8位字W之外(埯stty pass8命o Q,還需要設|bash的入換,可以在登錄腳?profile文g中包括以下設|:
bind 'set convert-meta off'
bind 'set meta-flag on'
bind 'set output-meta on'
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/chenguoda/archive/2008/06/08/2524292.aspx
next 可以单理解ؓ跌后面的代码,如果next被执行,那么它后面的代码都不会被执行了?/td> |
一个awk E序是一对以模式(pattern) 与大括号框v来的操作(action) l合而成的,或许Q还会加上实现操作细节的函数(function ) 。针Ҏ个匹配于输h数据的模式,操作会被执行Q且所有模式都会针Ҏ条输录而检查。模式或操作可省略其中一个。如果模式省略,则操作将被应用到每条输h记录; 如果操作省略Q则默认操作为打印匹配之记录在标准输Z。以下是传统awk E序的配|?
pattern {action} 如模式匹配,则执行操?
pattern {action} 如模式匹配,则打印记?
虽然Q模式多半是数字或字W串表达式,不过awk 以保留字BEGIN 与END 提供两种Ҏ模式?
与BEG 工N 兌的操作只会执行一ơ,在Q何命令行文g或一般命令行赋D处理之前Q但是在M开头的一V 选项指定已经完成之后?
END 操作也是只执行一ơ,用于所有输入数据已被处理完之后。它多半用于产生摘要报告Q或是执行清除操作?
BEGIN 与END 模式可以是Q意顺序,可以存在于awk E序内的M位置。不q,Z方便Q我们通常BEGIN 模式攑֜E序的第一个位|,而将END 模式攑֜最后?
2. 注释与空?
awk 里的注释是从# 开始到该行l束Q就像在Shell 里那栗空行等同于I的注释?
3. 字符串与字符串表辑ּ
awk 字符串包含零臛_个字W,且在字符串的长度上没有限Ӟ视可用内存而定?
字符串的比较Q用的是传统的关p运符Q?=( 相等) ?=( 不等) ?lt;( 于) ?lt;=( 于{于) ?gt;( 大于) Q以?gt;=( 大于{于》。比较后q回l 为真Q? 为假。比较不同长度的字符Ԍ且其中一个字W串为另一个的初始子字W串Ӟ较短的会定义为小于较长的那个Q因此,“A ”< “AA ”的gؓ真?
awk q无Ҏ的字W串接箋q算W。也是_两个q箋字符Ԍ会自动地q接在一赗以下每一l赋D|标量变量。ؓ相同的具有四个字W的字符?
s = “ABCD ”
s = “AB ”“CD ”
s = “A ”“B ”“CD ”
s = “A ”“B ”“C ”“D ”
字符串不需要是常数Q如果我们l上q的赋?
t= s s s
则t 的gؓ“ABCDABCDABCD “?
数字{换ؓ字符Ԍ通过数字q接I字W串卛_
n =123 Q?
接着是:
s = ““ n Q把?#8220;123 ”赋给s ?
awk 功能强大的地方大多来自于它对正则表达式的支持。有两个q算W:~( 匚w) ?~( 不匹? 让awk 更容易用正则表辑ּQ?#8221;ABC ”~ ”^[A-Z]+$ “Q结果ؓ真?
4. 数g数D辑ּ
所有awk 里的数字Q都以双_度的点DC。QҎ可以包含一个末端以字母e( 或E) 所表示?0 ơ方指数以及可选地带正负号的一个整数。D例来?0.03125, 3.125e-2, 3125e-5 ?.003125E1 Q同样都是表C?/32 。因为awk 里所有算术都是Q点算术?
awk q没有提供字W串转数字的函数Q不qawk 的做法很单:只要加个零到字符串里Q例如:s="123" Q接着是n=0+s Q便数?23 赋值给n 了?
5. awk 的数D符
? 一Qawk 的数D符( 优先U由大到排?
q算W?nbsp; 说明
++ -- 增加与减? 前置或后|?
^ ** 指数( 右结合?
! + - 非、一?unary) 加号、一元减?
* / % 乘、除、余?
+ - 加、减
< <= == != > >= 比较
&& 逻辑AND( ?
|| 逻辑OR( ?
?: 三元条g?
= += -= *= /= %= ^= **= 赋? 右结合?
6. 标量变量
保存单一值的变量叫做标量变量?
a wk 的变量名U必MACSII 字母或下划线开始,然后选择性地接上字母、下划线及字。因此,变量名称要匹配正则表辑ּ[A-Za-z-][A-Za-z_0-9]* 。变量名U在实际上ƈ没有长度的限制。awk 的变量名U是与大写有关?foo, Fo 。与FOO 是完全不同的三个名称。一般用上以及用法? L习惯Q将局部变量全设ؓ写、全局变量W一个字母ؓ大写Q而内建变量则全是大写?
7. 数组变量
awk 允许在数l名UC后,以方括号Q意数字或字符串表辑ּ 括v来作为烦引。例?
telephone["Alice"]= “555-0134"
telephone["Bob"]= “555-0135"
telephone["Carol”]= “555-0136"
telephone["Don"]= “555-0141"
以Q意gؓ索引的数l,UC为关联数l,因ؓ它们的名UC值是相关联的。重要的是,awk 其应用于数l中Q允许查? find ) 、插?insert ) 以及删除( remove) {操作,在一定的旉内完成,与存储多项目无兟?
一个变量不能同时用作标量变量和数组变量。当你应用delet 。语句删除数l的元素
(element] 的时候,不会删除它的名称。因此。像q样的代?
x[1]=3
delete x
x=789
会引发awk 发出提示Q告诉你不可以给数组名称赋?
8. 命o行参?
awk 通过内徏变量ARGC( 参数计数) 与ARGV( 参数向量Q或参数? Q让命o行参?
可用。下面简短的E序说明其用?
[root@local~]#cat showargs.awk
BEGIN{
print ”ARGC= ”QARGC
for (k=0;k<ARGC; k++)
print "ARGV[”k”]=[”ARGV[k] “
}
再来看看它用在一般awk 命o行上Q会产生什么样的结?
[root@local~]# awk -v One=1 -v Two=2 -f showargs.awk Three=3 file1 Four=4 filet2 file3
ARGC=6
ARGV[0]=[awk]
ARGV[1]=[Three=3]
ARGV[2]=[file1]
ARGV[3]=[Four=4]
ARGV[4]=[file2]
ARGV[5]=[file3]
9. 环境变量
awk 提供讉K内徏数组ENV 工RON 中所有的环境变量:
[root@local~]#awk 'BEGIN {print ENVIRON["HOME"];print ENVIRON["USER]} ‘
/home/Jones
hones
通常你应ENVIRON 看成是一个只Ll?
10. 模式
模式由字W串?/ 或数D辑ּ构徏而成。常用的模式如下Q?
NF==0 选定I?
NF>3 选定拥有三个字段以上的记?
NR<5 选定W?1 到第 4 条记?
(FNR==3)&&(FILENAME~/[.] [ch]$/) 来源?C 源文件中选定记录 3
$1~/Jones/ 选定字段 1 里有 . ” jones “的记?
/[Xx][Mm][Ll]/ 选定含有‘ 'XML' 。的记录Qƈ忽略大小写差?
$0~/[Xx][Mm][Ll]/ 同上
11. 操作
以最单的形式来说Q纯print 意指在标准输ZQ打印当前的输入记录($0) Q接着是输录分隔字W?ORS 的|默认为单一换行字符。因此,下面q些E序所做的全是相同的操?
1 模式为真Q默认操作ؓ打印
NR>0 {print} 有记录时打印( 恒ؓ?
1 {print} 模式为真。则打印Q这是默认?
{print} 无模式则视ؓ真,明确的打华ͼq是默认?
{print $0} 相同Q但打印明确的?
下面的例子已l是完整的awk E序。在每一个中Q我们都只显C前三个输入字段Qƈ通过省略选定模式Q选定所有的记录。awk E序语句以分号分隔,而且我们会用些略微不同的操作代码,以修改输出字D分隔字W?
[root@local~]#echo ‘one two three four'| awk ‘{print $1,$2,$3}’
one two three
[root@local~]#echo ‘one two three four'| awk ‘{OFS=”…”;print $1,$2,$3}’
one…two…three
[root@local~]#echo ‘one two three four'| awk ‘{OFS=”\n”;print $1,$2,$3}’
one
two
three
改变输出字段分隔字符而没有指定Q何字D,不会改变$0:
[root@local~]#echo ‘one two three four'| awk ‘{OFS=”\n”;print $0}’
one two three four
不过Q如果我们更改输出字D分隔字W,q指定至一个字D? 即我们未变更其? Q?
强制以新的字D分隔字W重新组合记录,则结果ؓ:
[root@local~]#echo ‘one two three four'| awk ‘{OFS=”\n”;$1=$1;print $0}’
one
two
three
four
12. 在awk 中的单行E序
1.UNIX 单词计数E序wc;
[root@local~]#awk ‘{C+=length($0)+1;w+=NF} END {print NR, W, C}’
2. 撇开NUL 字符问题Qawk 其实可以L取代cat Q下面这两个例子会生相同输?
[root@local~]# cat*.xml
[root@local~]# awk 1*.xml
3. 要将原始数据值及它们的对数打Cؓ单栏的数据文Ӟ可?
[root@local~]# awk ‘{print $1, log($1)}’file(s)
4. 在以I白分隔字段的表gQ报告第n 栏的?
[root@local~]# awk -v COLUMN=n ‘{sum+=$COLUMN} END {print sum} ’file (s)
5. 微调上述报告Q生字Dn 的^均?
[root@local~]# awk -v COLUMN=n ‘{sum+=$COLUMN} END {print sum/NR } ’file (s)
6. 针对p文g( 其记录包含描qC金额于最后一个字D? Q打印花ҎL。可使用内徏变量NF 计算d?
[root@local~]# awk’{sum+=$NF; print $0, sum}’files)
7. q里是三U查找文件内文本的方?
[root@local~]#egrep ‘pattern|pattern’ file (s)
[root@local~]#awk ‘/pattern|pattern/’file (s)
[root@local~]#awk ‘/pattern}pattern/ {print FILENAME ”: ”FNR ”: ”$0} ’file(s)
8. 如果你要限制仅查?00 一150 行,可以通过两个工具E序Q再搭配道Q不q这么做会漏掉位|信?
[root@local~]#sed -n -e 100,150p -s file(s) | egrep 'pattern'
使用GNU sed 要搭?s 选项Q才能ؓ每个文g重新开始行~号。另外,你也可以通过awk Q用比较花哨的模式来做:
[root@local~]#awk ‘(100<=FNR) && (FNR <= 150) && /pattern/\
{print FILENAME ”:” FNR ”:”$0}’file(s)
9. 要在一个四栏表格里Q调换第二与W三栏,假设它们是以制表字符分隔Q那么可?
使用下面三种方式的其中一U?
[root@local~]#awk -F'\t’-v OFS='\t’{print $1, $3, $2, $4}’old > new
[root@local~]#awk ‘BEGIN{FS=OFS="\t"}{print $1, $3 Q?2 Q?4} ’old>new
[root@local~]#awk –F ‘\t’{print $1"\t" $3"\t" $2"\t" $4}’old>new
10. 要将各栏分隔字符由制表字W? 在此?#183;昄) 转换?amp; Q可在以下两U方式择一:
[root@local~]#sed -e 's/ ·/&/g' file(s)
[root@local~]#awk ‘{BEGIN{FS="\t";OFS= “& ”}{$1=$1; print} ’file(s)
11. 下面q两个管道,都ؓ删除已排序流里的重复?
[root@local~]#sort file(s)|uniq
[root@local~]# sort file(s)|awk ‘Last!=$0 { print }{Last=$0}’
12. 回车字W? 换行字符的行l结Q一致{换ؓ以换行字W作l结Q可在下列方
式中选择一U?
[root@local~]#sed –e ‘s/\r$//’ file(s)
[root@local~]#sed –e ‘s/^M$//’ file(s)
[root@local~]# mawk ‘BEGIN {RS=“\r\n"} {print}’file(s)
13. 要将单空格的文本行,转换为双I格的行Q可在下列方式选择一U?
[root@local~]#sed –e ‘/s/$/\n/ ’file(s)
[root@local~]#awk ‘BEGTN{ ORS = "\n\n"){print}’file(s)
[root@local~]#awk ‘BEGIN{ ORS="\n\n" }1 ’ file(s)
[root@local~]#awk {print $0 “\n”} ’ file(s)
[root@local~]#awk ‘{print;print ” ”} ’ file(s)
13. 语句
13.1. 条g语句
if(expressionl)
stateme 刀t1
else if(expression2)
statement2
else if(expression3)
statement3
else if(expressionk)
statementk
else
statementk+l
13.2. 重复执行
awk 提供?4 U重复执行语?( 循环 ):
1. 循环在v始处使用l束试 :
while(expression)
statement
2. 循环在结֤使用l束试 :
do
statement
while (expression)
3. 循环执行可计数的ơ数 :
for(expr1;expr2; expr3)
statement
4. 循环处理兌数组里的元素 :
for(key in array)
statement
例如Q?
for Qname in telephone)
print name“\t" telephone[name]
13.3 数组成员试
成员试key in array 是一个表辑ּ: 如果key 为array 的一个烦引元素,则计ؓ1( ? 。如果key 不是array 的一个烦引元素,?(key in array) ? ?
对于h多下?subscript) 的数l,在测试时Q请使用圆括Pq以逗点分隔下标列表:(i Qj Q?#8230;Qn)in array
成员试不可能徏立数l元素,然而引用元素时Q如果元素不存在Q便会徏立它。因此你应该q么?
if("Sally" in telephone)
print "Sally is in the directory"
而非:
if (telephone["Sally"]!= ””)
print "Sally is in the directory"
因ؓW二UŞ式会在她(Sally) 不存在时Q将其加入到目录里,q拥有一个空电话L?
重点? 你必能够区分寻扄?index) 与寻扄定?value) 的差异。烦引成员测试需要固定的旉Q而值的查找旉是与数组里元素的个数成正比,q点我们在先前已通过break 语句内的for 循环解释q了。如果你需要时常用到这两种q算Q那么构建反索引数组会比较实?
for (name in telephone)
name_by_telephone[telephone[name]]=name
接下来,你就可以使用name_by_telephone ["555-0136"] 在一定时间内扑ֈ”Carol" 。当Ӟq里假定所有的值是唯一? 如果q两人共享同一个电话,则name_by_telephone 数组只会记录最后一个名U。只要稍做修改就能解册个问?
for (name in telephone)
{
if (telephone[name] in name_by_telephone)
name_by_telephone[telephone[name]]=\
name_by_telephone [telephone[name]) “\t”name
e1se
name_by_telephone[telephone[name]]=name
现在Qname_by_telephone 卛_含了以制表字W分隔的h相同电话L的h名列表?
14. 用户控制输入
awk 也可以通过的getline 语句做这件事。getline 会返回一个|当输入被成功dӞ它的q回gؓ++I Q而返回gؓ0 Ӟ则表C在文gl尾Q?1 则表C错误。它的用法很多,见表?
语法 说明
getline 从当前输入文件中Q读取下一条记录,存入$0 Qƈ更新NF, NR 与FNR
getline var 从当前输入文件中Q读取下一条记录,存入var Qƈ更新NR 与FNR
getline<file 从file 文g中,d下一条记录,存入$0 Qƈ更新NF, NR 与FNR
getline var<file 从file 文g中,d下一条记录,存入var Qƈ更新NF, NR 与FNR
cmd|getline 从外部命令cmd d下一条记录,存入$0 Qƈ更新NF
cmd|getline var 从外部命令cmd d下一条记录,存入var
命o道在awk 里可以发挥强大的功能。管道可以在字符字符串中标明Q也可以包含?
意的Shell 命o。这里是与getline 搭配使用Q如?
"date" I getline now
close("date")
print "The current time is".now
接下来说明的? 如何在@环里使用命o道:
command="head -n 15 /etc/hosts"
while((command I getline s)>0)
print s
close(command)
15. 执行外部E序
q里是解决电话名录排序问题较短的E序ҎQ用时性文件与systemty Q而非awk 道:
tmpfile= “/tmp/telephone.tmp^
for (name in telephone>
print name "\t" telephone[name]>tmpfile
close(tmpfilej
system("sort < tmpfile “)
临时性文件必d调用system() 之前关闭Q以保M~冲出都正确地记录在文g内?
对于被system() 执行的命令ƈ不需要调用close() Q因为close() 仅针对以I/O 重定向运符所打开的文件或道Q还有getline, print 或printf ?
传递给system[f 的命令可包含数行
system("cat <<EOFILE\nuno\ndos\ntres\nEOFILE"
它生的输出和从嵌入文g复制到标准输Z?
Un0
das
tres
16. 用户自定义函?
函数定义如下:
function name(argl, }rg2, …Qargn
{
statements
}
指定的参数在函数体中用来当作局部变量,它们会隐藏Q何相同名U的全局性变量。函C可用于程序它处,调用的Ş式ؓ:
name(exprl, expr2, …Qexpn) 忽略M的返回?
result=name(exprl, expr2, …Qexprn) 返回值存储到result ?
在每个调用点上的表达式,都提供初始值给函数参数型变量。以圆括hh的参敎ͼ必须紧接于函数名UC后,中间没有MI白?
Ҏ量参数所做的变动Q调用者无从得知,不过Ҏl的变动可看见了。换句话_标量Z?by vaule ) Q而数l则Z引用(by reference): q对C 语言也是q样?
函数体里的return expression 语句会终止主体的执行Qƈexpression 的g控制权传l调用点。如果expression 省略Q则q回值由实现期定义。我们测试过的所有系l,q回的不是数字零是I字W串?
17. 字符串函?
17.1. 子字W串提取
提取子字W串的函?substr(string, start, 1en) Q会q回一份由string 的start 字符开始,共len 个字W长度的子字W串副本。字W的位置Q从1 开始编?substr("abcde", 2, 3) 返回。bcd" ?len 参数可省略,省略Ӟ则默认ؓlength(string)-start+1 Q选出字符串的剩余部分?
17.2. 字符串大写转换
tolower(string) 会返回将所有字母改为同义的写的string 副本Q而toupper(string) 则返回被改ؓ大写字母的string 副本。所以tolower("aBcDeF123") q回”abcdef123",toupper("aBcDeF123") q回"ABCDEF123" ?
17.3. 字符串大写转换
index(string, find) 查找string 里是否有字符串find Q然后返回string 里find 字符串的起始位置Q如果在string 里找不到find Q则q回0 。例如index("abcdef","de") 会返? ?
17.4. 字符串匹?
match Qstring, regexp) string 与正则表辑ּregexp 匚wQ如果匹配,则返?
匚wstring 的烦引,不匹配,则返? 。这U方式提供了比表辑ּ(string~regexp) q多的信息,后者只能得到计? ? 。另外match ( ) 也具有一个有用的副作? 它会全局变量RSTART 设ؓ在string 中要开始匹配的索引|而将RLENGTH 设ؓ要匹配的长度。而匹配子字符串则以substr(string, RSTART, RLENGTH) 表示?
17.5. 字符串替?
awk 在字W串替换功能上,提供两个函数:sub(regexp, replacement, target) 与gsub(regexp, replacement, target), sub() target 与正则表辑ּregexp q行匚wQ将最左边最长的匚w部分替换为字W串replacement 。gsub() 的运行则有点cMQ不q它会替换所有匹配的字符? 前置g 表示global 全局之意) ?
17.6. 字符串替?
awk 针对当前输h记录$0 自动提供了方便的分割为字1, $}, …?NF Q也可以函数来做:split(string, array, regexp) string 切割为片D,q存储到array 里的q箋元素。在数组里,片段攄在匹配正则表辑ּregexp 的子字符串之间。如果regexp 省略Q则使用内徏字段分隔字符FS 的当前默认倹{函Cq回array 里的元素数量?
17.7. 字符串重?
join() 可确保参数数l不会被引用刎ͼ除非索引是在范围之内。否则,一个具有数l长度ؓ0 的调用可能会建立arrayfl3 Q而修改了调用者的数组。插人的字段分隔字符为普通字W串Q而非正则表达式,所以针对传递给split() 的一般正则表辑ּQjoin() 不会重徏_的原始字W串?
17.8. 字符串格式化
最后一个与字符串相关的函数是在用户控制下格式化数字与字W串:sprintf (format,expression1, expression2, …) Q它会返回已格式化的字符串作为其函数倹{printf() 的运行方式也是这P只不q它会在标准输出或重定向的文件上昄格式化后的字W串Q而不是返回其函数倹{较新的E序语言以更强大的格式化函数来取代格式控制字W串Q但相对而言让代码变得很冗长。按照传l的文本处理应用来说Qsprintf 与printf
18. 数值函?
函数 说明
atan2(y, x) y q回y/x 的反正切Qg?pai ?pai 之间?
cos(x) q回x 的余弦? 以弧?radians) 计算) Q该g?1 ?1 之间
exp(x) q回x 的指敎ͼex,
int(x) q回x 的整数部分,截去前置?
log(x) q回x 的自然对数?
rand() q回q_分布的虚拟随机r,O<=r<l
sin(x) q回x 的正弦? 以弧?radians] 计算) Q该g?1 ?1 之间
sqrt(x) q回x 的^?
srand(x) 讄虚拟随机产生器的U子为x Qƈq回正确的种子。如果省略x Q则使用当前旉( 以秒? 。如果。rand ( ) 未被调用Q则awk 在每ơ执行时会从相同的默认种子开?mawk 则不会?
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/wzhwho/archive/2010/04/21/5513791.aspx
awk 'BEGIN {system("echo \"Input your name:\\c\""); getline d;print "\nYour name is",d,"\b!\n"}'
用(""Q和\" \" \\转义?/p>
system - execute a shell command Q)里面接入命o
awkE序中我们可以用system() 函数去调用shell命o
如:awk 'BEGIN{system("echo abc")}' file
echo abc ׃做ؓ“命o?#8221;Q由shell来执行,所以我们会得到以下l果Q?br>
root@ubuntu:~# awk 'BEGIN{system("echo abc")}'
abc
root@ubuntu:~#
root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1" "v2)}'
abc
root@ubuntu:~#
root@ubuntu:~# awk 'BEGIN{v1="echo";v2="abc";system(v1 v2)}'
/bin/sh: echoabc: command not found
root@ubuntu:~#
root@ubuntu:~# awk 'BEGIN{v1=echo;v2=abc;system(v1" "v2)}'
root@ubuntu:~#
从上面的例子Q我们简单的分析一下awk是怎样调用system的:
如果systemQ)括号里面的参数没有加上双引号的话Qawk认ؓ它是一个变量,它会从awk的变量里面把它们先置换ؓ帔RQ然后再回传lshell
如果systemQ)括号里面的参数有加上双引L话,那么awkq接把引号里面的内容回传给shellQ作为shell?#8220;命o?#8221;
二。用print cmd | “/bin/bash”
root@ubuntu:~# awk 'BEGIN{print "echo","abc"| "/bin/bash"}'
abc
root@ubuntu:~#
root@ubuntu:~# awk 'BEGIN{print "echo","abc",";","echo","123"| "/bin/bash"}'
abc
123
root@ubuntu:~#
三。ȝ
无论使用systemQ)q是print cmd | “/bin/bash”
awk都是新开一个shellQ在相应的cmdline参数送回lshellQ所以要注意当前shell变量与新开shell变量问题
1.1
root@ubuntu:~# abc=12345567890
root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'
root@ubuntu:~#
1.2
root@ubuntu:~# export abc=12345567890
root@ubuntu:~# awk 'BEGIN{system("echo $abc")}'
12345567890
root@ubuntu:~#
2.1
root@ubuntu:~# abc=1234567890
root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'
root@ubuntu:~#
2.2
root@ubuntu:~# export abc=1234567890
root@ubuntu:~# awk 'BEGIN{print "echo","$abc"| "/bin/bash"}'
1234567890
root@ubuntu:~#
以上例子Q没有export的话Q那些变量都是只存在于当前shell变量中,所以都是echo不出来的 Q?br>而用了 export的都是环境变量,所以awk调用新的shell时候,可以echo出来
split命o
语法:komy@komy-vmware:~$ split [-bl] 输入文g 输出文g
参数说明
-b :以文件大来?/font>
-lQ以行数来分
例如split -l 100 test.txt out
是把test.txt?00行输Z个文件outaa,outab,outcd以此cL。。。实C文本文g的分剌Ӏ?/font>
split -b 100k test.txt out
是把test.txt?00KB输出一个文件outaa,outab,outcd以此cL?/font>
q两个命令对于手机看说有限制的情况下很受用。。?/font>
不仅仅如此cat 命o可将q些分割后的文g合ƈZ个文Ӟq定向?#8220;largefile”文g中(largefile定的文g名)?
komy@komy-vmware:~$ cat out* > largeflie
shell文本处理斚wQ主要是有sedQawkq两把刀?br> 光给你个shell你进行文本处理是做不到的Q当然简单的q可以?br> perl里有正则表达式引擎,能针Ҏ本进行拆分替换等复杂操作Q关键是Qperl不用fork出新的进E来处理q些事情Q而shell需要用管道等通过q些sedQawk的进E来处理Q至就多出部分q程的开销?br> 而且Q管道这个东西,原本一个工具一ơ能完成的Q务,在需要经qsedQ和awk{多ơ管道。效率可惌知?br> 其实你这个问题问的有点弱智,SHELL是什么? SHELL只是一个接口,大部分的功能全靠外部E序来完成?br>而Perl是一U语aQ基本上什么事情都能做?/td> |
-k [ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
The sort key includes all characters beginning with the field specified by the FStart variable and the column specified by
the CStart variable and ending with the field specified by the FEnd variable and the column specified by the CEnd variable.
If Fend is not specified, the last character of the line is assumed. If CEnd is not specified the last character in the
FEnd field is assumed. Any field or column number in the KeyDefinition variable may be omitted. The default values are:
FStart
Beginning of the line
CStart
First column in the field
FEnd
End of the line
CEnd
Last column of the field
If there is any spaces between the fields, sort considers them as separate fields.
The value of the Modifier variable can be one or more of the letters b, d, f, i, n, or r. The modifiers apply only to the
field definition they are attached to and have the same effect as the flag of the same letter. The modifier letter b
applies only to the end of the field definition to which it is attached. For example:
-k 3.2b,3r
specifies a sort key beginning in the second nonblank column of the third field and extending to the end of the third
field, with the sort on this key to be done in reverse collation order. If the FStart variable and the CStart variable fall
beyond the end of the line or after the FEnd variable and the CEnd variable, then the sort key is ignored.
A sort key can also be specified in the following manner:
[+[FSkip1] [.CSkip1] [Modifier] ] [-[FSkip2] [.CSkip2] [Modifier]]
The +FSkip1 variable specifies the number of fields skipped to reach the first field of the sort key and the +CSkip
variable specifies the number of columns skipped within that field to reach the first character in the sort key. The -FSkip
variable specifies the number of fields skipped to reach the first character after the sort key, and the -CSkip variable
specifies the number of columns to skip within that field. Any of the field and column skip counts may be omitted. The
defaults are:
FSkip1
Beginning of the line
CSkip1
Zero
FSkip2
End of the line
CSkip2
Zero
The modifiers specified by the Modifier variable are the same as in the -k flag key sort definition.
The field and column numbers specified by +FSkip1.CSkip1 variables are generally one less than the field and column number
of the sort key itself because these variables specify how many fields and columns to skip before reaching the sort key.
For example:
+2.1b -3r
specifies a sort key beginning in the second nonblank column of the third field and extending to the end of the third
field, with the sort on this key to be done in reverse collation order. The statement +2.1b specifies that two fields are
skipped and then the leading blanks and one more column are skipped. If the +FSkip1.CSkip1 variables fall beyond the end of
the line or after the -FSkip2.CSkip2 variables, then the sort key is ignored.
Note: The maximum number of fields on a line is 10.
Z防止某些|站的恶性{载,特在每篇文章前加入此信息Q还望读者体谅?/strong>
===
[正文开始]
有时候学习脚本,你会发现sort命o后面跟了一堆类?k1,2Q或?k1.2 -k3.4的东东,有些匪夷所思。今天,我们来搞定它?k选项Q?/p>
1 准备素材
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
W一个域是公司名UͼW二个域是公思h敎ͼW三个域是员工^均工资。(除了公司名称Q其他的别信Q都瞎写的^_^Q?/p>
2 我想让这个文件按公司的字母顺序排序,也就是按W一个域q行排序Q(q个facebook.txt文g有三个域Q?/strong>
$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
看到了吧Q就直接?k 1讑֮可以了。(其实此处q不严格Q稍后你׃知道Q?/p>
3 我想让facebook.txt按照公司人数排序
$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
不用解释Q我怿你能懂?/p>
但是Q此处出C问题Q那是baidu和sohu的公思h数相同,都是100人,q个时候怎么办呢Q按照默认规矩,是从W一个域开始进行升序排序,因此baidu排在了sohu前面?/p>
4 我想让facebook.txt按照公司人数排序 Qh数相同的按照员工q_工资升序排序Q?/strong>
$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
看,我们加了一?k2 -k3p决了问题。对_sort支持q种讑֮Q就是说讑֮域排序的优先U,先以W?个域q行排序Q如果相同,再以W?个域q行排序。(如果你愿意,可以一直这么写下去Q设定很多个排序优先U)
5 我想让facebook.txt按照员工工资降序排序Q如果员工h数相同的Q则按照公司人数升序排序Q(q个有点隑ֺ喽)
$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
此处有用了一些小技巧,你仔l看看,?k 3后面偷偷加上了一个小写字母r。你xQ再l合我们上一文?/font>Q能得到{案么?揭晓Qr?r选项的作用是一LQ就是表C逆序。因为sort默认是按照升序排序的Q所以此处需要加上r表示W三个域Q员工^均工资)是按照降序排序。此处你q可以加上nQ就表示对这个域q行排序Ӟ要按照数值大进行排序,举个例子吧:
$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
看,我们L了最前面?n选项Q而是它加入C每一?k选项中了?/p>
6 -k选项的具体语法格?/strong>
要l往下深入的话,׃得不来点理论知识。你需要了?k选项的语法格式,如下Q?/p>
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
q个语法格式可以被其中的逗号Q?#8220;Q?#8221;Q分Z大部分,Start部分和End部分?/p>
先给你灌输一个思想Q那是“如果不设定End部分Q那么就认ؓEnd被设定ؓ行尾”。这个概念很重要的,但往往你不会重视它?/p>
Start部分也由三部分组成,其中的Modifier部分是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start?/p>
C.Start也是可以省略的,省略的话pCZ本域的开头部分开始。之前例子中?k 2?k 3是省略了C.Start的例子喽?/p>
FStart.CStartQ其中FStart是表示使用的域Q而CStart则表C在FStart域中从第几个字符开始算“排序首字W?#8221;?/p>
同理Q在End部分中,你可以设定FEnd.CEndQ如果你省略.CEndQ则表示l尾?#8220;域尾”Q即本域的最后一个字W。或者,如果你将CEnd讑֮?(?Q也是表C结ֈ“域尾”?/p>
7 H发奇想Q从公司英文名称的第二个字母开始进行排序:
$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
看,我们使用?k 1.2Q这pC对W一个域的第二个字符开始到本域的最后一个字Wؓ止的字符串进行排序。你会发现baidu因ؓW二个字母是a而名列榜首。sohu和googleW二个字W都是oQ但sohu的h在google的o前面Q所以两者分别排在第二和W三。guge只能屈居W四了?/p>
8 又突发奇惻IQ只针对公司英文名称的第二个字母q行排序Q如果相同的按照员工工资q行降序排序Q?/strong>
$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
׃只对W二个字母进行排序,所以我们用了-k 1.2,1.2的表C方式,表示我们“?#8221;对第二个字母q行排序。(如果你问“我?k 1.2怎么不行Q?#8221;Q当然不行,因ؓ你省略了End部分Q这意味着你将对从W二个字母v到本域最后一个字Wؓ止的字符串进行排序)。对于员工工资进行排序,我们也用了-k 3,3Q这是最准确的表qͼ表示我们“?#8221;Ҏ域进行排序,因ؓ如果你省略了后面?Q就变成了我?#8220;对第3个域开始到最后一个域位置的内容进行排?#8221;了?/p>
9 在modifier部分q可以用到哪些选项Q?/strong>
可以用到b、d、f、i、n ?r?/p>
其中n和r你肯定已l很熟悉了?/p>
b表示忽略本域的签到空白符受?/p>
d表示Ҏ域按照字兔R序排序(卻I只考虑I白和字母)?/p>
f表示Ҏ域忽略大写q行排序?/p>
i表示忽略“不可打印字符”Q只针对可打印字W进行排序。(有些ASCII是不可打印字符Q比如\a是报警,\b是退|\n是换行,\r是回车等{)
10 思考思考关?k?u联合使用的例子:
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
q是最原始的facebook.txt文g?/p>
$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000
当设定以公司员工域进行数值排序,然后?u后,sohu一行就被删除了Q原?u只识别用-k讑֮的域Q发现相同,将后箋相同的行都删除?/p>
$ sort -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
$ sort -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
q个例子也同理,开头字W是g的guge没有幸免于难?/p>
$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
咦!q里讄了两层排序优先的情况下Q?u没有删除Q何行。原?u是会权衡所?k选项Q将都相同的才会删除Q只要其中有一U不同都不会L删除?)Q不信,你可以自己加一行sina 100 4500试试看)
11 最诡异的排序:
$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
以第二个域的W二个字W开始到W三个域的第一个字W结束的部分q行排序?/p>
W一行,会提? 3Q第二行提取00 5Q第三行提取00 4Q第四行提取10 5?/p>
又因为sort认ؓ0于00于000于0000….
因此0 3肯定是在W一个?0 5肯定是在最后一个。但Z?0 5却在00 4前面呢?Q你可以自己做实验思考一下。)
{案揭晓Q原?#8220;跨域的设定是个假?#8221;Qsort只会比较W二个域的第二个字符到第二个域的最后一个字W的部分Q而不会把W三个域的开头字W纳入比较范围。当发现00?0相同Ӟsort׃自动比较W一个域M。当然baidu在sohu前面了。用一个范例即可证实:
$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
12 有时候在sort命o后会看到+1 -2q些W号Q这是什么东东?
关于q种语法Q最新的sort是这么进行解释的Q?/p>
On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys. POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.
原来Q这U古老的表示方式已经被淘CQ以后可以理直气壮的鄙视使用q种表示Ҏ的脚本喽Q?/p>
Qؓ了防止古老脚本的存在Q在q再说一下这U表C方法,加号表示Start部分Q减可CEnd部分。最最重要的一ҎQ这U方式方法是?开始计数的Q以前所说的W一个域Q在此被表示为第0个域。以前的W?个字W,在此表示为第1个字W。明白?Q?/p>
l束语:
本文是互联网上仅有的比较全的关于sort的k选项的论q文章,如需转蝲请务必注?#8220;转自Linux大棚-Linux主题博客”Q谢谢各?)
sort?k选项基本是q堆内容了,如果大家有什么补充,qa?) Ƣ迎交流Q?/strong>
1 sort的工作原?/strong>
sort文件的每一行作Z个单位,怺比较Q比较原则是从首字符向后Q依ơ按ASCII码D行比较,最后将他们按升序输出?/p>
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
2 sort?u选项
它的作用很简单,是在输中去除重复行?/p>
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear
pear׃重复?u选项无情的删除了?/p>
3 sort?r选项
sort默认的排序方式是升序Q如果想Ҏ降序Q就加个-r搞定了?/p>
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1
4 sort?o选项
׃sort默认是把l果输出到标准输出,所以需要用重定向才能将l果写入文gQŞ如sort filename > newfile?/p>
但是Q如果你x排序l果输出到原文g中,用重定向可就不行了?/p>
[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然number清空了?/p>
在q个时候,-o选项出现了,它成功的解决了这个问题,让你攑ֿ的将l果写入原文件。这或许也是-o比重定向的唯一优势所在?/strong>
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1
5 sort?n选项
你有没有遇到q?0?的情况。我反正遇到q。出现这U情冉|׃排序E序这些数字按字符来排序了Q排序程序会先比??Q显?,所以就?0攑֜2前面喽。这也是sort的一贯作风?/p>
我们如果x变这U现Ӟp使用-n选项Q来告诉sortQ?#8220;要以数值来排序”Q?/p>
[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19
6 sort?t选项?k选项
如果有一个文件的内容是这P
[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
q个文g有三列,列与列之间用冒号隔开了,W一列表C水果类型,W二列表C水果数量,W三列表C水果h根{?/p>
那么我想以水果数量来排序Q也是以第二列来排序,如何利用sort实现Q?/p>
q好Qsort提供?t选项Q后面可以设定间隔符。(是不是想起了cut和paste?d选项Q共鸣~~)
指定了间隔符之后Q就可以?k来指定列C?/p>
[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
我们使用冒号作ؓ间隔W,q对第二列来进行数值升序排序,l果很o人满意?/p>
7 其他的sort常用选项
-f会将写字母都{换ؓ大写字母来进行比较,亦即忽略大小?/p>
-c会检查文件是否已排好序,如果乱序Q则输出W一个ؕ序的行的相关信息Q最后返?
-C会检查文件是否已排好序,如果乱序Q不输出内容Q仅q回1
-M会以月䆾来排序,比如JAN于FEB{等
-b会忽略每一行前面的所有空白部分,从第一个可见字W开始比较?/p>
未完待箋Q敬h待:《sort命o的k选项大讨论?/strong>
#! /bin/bash
for file in *.log
do
awk 'BEGIN{var=" ' "$file" ' "}END{print var;}' "$file"
done
在这里最让hh的是单引号和双引?/span>
我们可以利用bash -x test.sh来执行脚本,其会脚本中的shell变量展开Q便于调?/strong>
’单引号中除(’Q都为原本字W,没有Ҏ意义
"双引号中除( $`"Q?/strong> 都ؓ原本字符Q没有特D意?/strong>
因此Q上q可以展开?
W一ơ:
awk 'BEGIN{var="a.log"}END{print var;}‘ a.log
W二ơ:
awk 'BEGIN{var="b.log"}END{print var;}‘ b.log
如果其写成 awk 'BEGIN{var=' "$file" '}END{print var;}' "$file"Q则展开为:
W一ơ:
awk 'BEGIN{var=a.log}END{print var;}‘ a.log
W二ơ:
awk 'BEGIN{var=b.log}END{print var;}‘ b.log
会报错,因ؓawk中字W串要用双引hh
其分解成以下这P便于理解Q?/strong>
'BEGIN{var=" ' "$file" ' "}END{print var;}' q三部分为字W串q接关系
## eval用法三例 ##
## shell:/bin/sh ##
## yhc 2002.09.26 18:00 ##
#例一:
#L合符条g的变量名,然后该变量的D予另一变量
v1=aaa
v2=bbb
c=1
if [ $c -eq 1 ]
then
vname=v$c #扑ֈW合条g的变量名为v1
eval vvv="$"$vname ; echo vvv: $vvv #变量v1的D予vvv,?使vvv=aaa
eval vvv='$'$vname ; echo vvv: $vvv #变量v1的D予vvv,?使vvv=aaa
#eval vvv=$$vname ; echo vvv: $vvv #错误用法
fi
#例二:#以变量v1的值aaa作ؓ变量?变量vaaa的D予这一新定义的变量aaa
v1=aaa ; vaaa="This is aaa"
#eval $v1=$vaaa ; echo aaa: $aaa #错误用法
#eval $v1="$vaaa" ; echo aaa: $aaa #错误用法
eval $v1='$vaaa' ; echo aaa: $aaa
#例三:
#以变量v1的值aaa作ؓ变量?q将变量名字串作为D予自w?br>v1=aaa ; vaaa="This is aaa"
eval $v1=$v1 ; echo aaa: $aaa #与例二的错误用法不同,q一用法是正的
eval $v1="$v1" ; echo aaa: $aaa #与例二的错误用法不同,q一用法是正的
eval $v1='$v1' ; echo aaa: $aaa
注意Q?br>
(1) 对信?1(D违?不能捕捉Q因为shell本n需要捕捉该信号去进行内存的转储?br>
(2) 在trap中可以定义对信号0的处?实际上没有这个信?Q?shellE序在其l止(?br>
执行exit语句)时发信号?br>
(3) 在捕捉到signal-list中指定的信号q执行完相应的命令之后, 如果q些命o没有
shellE序l止的话QshellE序l执行收Ch所执行的命令后面的命oQ这样将
很容易导致shellE序无法l止?br>
另外Q在trap语句中,单引号和双引h不同的,当shellE序W一ơ碰到trap语句Ӟ
把commands中的命o扫描一遍。此时若commands是用单引hh的话Q那么shell不会
对commands中的变量和命令进行替换, 否则commands中的变量和命令将用当时具体的值来
kill -l可以列出pȝ的信?/p>
通常我们需要忽略的信号有四个,卻IHUP, INT, QUIT, TSTPQ也是信号1, 2, 3, 24
使用q样的语句可以ɘq些中断信号被忽略:
trap "" 1 2 3 24 ?trap "" HUP INT QUIT TSTP
?trap Q? 2 3 24 ?trap HUP INT QUIT TSTP使其回复默认倹{?
用stty -a可以列出中断信号与键盘的对应Q分别执行上面的命o后,q行
tail -f /etc/passwd, 然后试用键盘中断,试试两种情况Q默认和忽略Q下有何不同?
更方便的是我们可以用在shell中用trap定义我们自己的信号处理程?/p>
gsub(r,s) | 在整?0中用s替代r |
gsub(r,s,t) | 在整个t中用s替代r |
index(s,t) |
q回s中字W串t的第一位置 |
length(s) |
q回s长度 |
match(s,r) |
试s是否包含匚wr的字W串 |
split(s,a,fs) | 在fs上将s分成序列a |
sprint(fmt,exp) | q回lfmt格式化后的exp |
sub(r,s) |
?0中最左边最长的子串代替s |
substr(s,p) | q回字符串s中从p开始的后缀部分 |
substr(s,p,n) |
q回字符串s中从p开始长度ؓn的后~部分 |