Blog

狼性犬与豺性犬

Content #

狗对人类的感情有相对独立的两个来源:一个是对首领狗的忠诚转移到了人身上,一个是对母亲的依恋之情得以永久性保留。这两种感情的强弱程度,在不同的狗身上,有不同的体现,这就决定了狼狗和豺狗性格的关键区别。与豺相比,在狼的生活中,群体的作用更重要。豺基本上是孤独的猎手,活动区域有限,而狼群在欧洲北部的森林中四处游荡,非常团结、排外,能够患难与共,群体的每个成员都会为了同伴而殊死搏斗。总有人说,狼群中会发生狼吃狼的事情。我强烈怀疑这种说法,因为雪橇犬无论如何都不会这样做,哪怕它们都要饿死了。这种意识显然不是人类灌输的。

狼的排外性很强,而且会不惜代价相互保护。狼性犬身上都体现出了狼的性格,使它们胜过豺性犬,后者见到每个人都是一副“您好幸会”的态度,不管是谁握着狗链,都会乖乖地跟着走。相反,狼性犬一旦对某人宣誓效忠,就永远是他的狗了,见到陌生人连大尾巴都不会摇一下。如果你曾经拥有一只矢忠不二的狼狗,肯定就再不会喜欢纯种的豺狗。不幸的是,狼性犬这种优点也可能让自己吃亏,矢忠不二也有消极的一面。一只成年的狼性犬绝对不会成为你的狗,这是显而易见的。但更坏的情况是,如果他已经是你的狗了,可是你又不得不离开它,它就会精神失常,既不会听你妻子的话,也不会听你孩子的话。在悲痛之中,它意志消沉,沦为街头一只无主的恶狗,放松了杀生的戒律,犯下累累恶行,祸害乡里。

此外,一只狼性犬,即便十分忠诚于你、爱你,它也不会特别听话。它可以为你赴死,却不一定会听你的话:至少我从来没法让这种狗绝对服从我——或许比我更厉害的驯狗师能做得更好。因此,走在城市的街道上,你很少会看到松狮犬紧跟着主人一起走,除非主人用绳子牵着它。如果你带着一只狼性犬在树林中散步,你没办法让它紧跟着你。它会和你保持松散联系,偶尔过来陪你一下。

豺性犬就不会这样,因为豺性犬很久以前就被驯化了,对主人的孺慕让它成为听从管教的伴侣。狼性犬勇敢忠诚,却不顺从,而豺性犬甘当你的奴仆,日日夜夜,无时无刻不在等待你的号令,再小的事也会坚决执行。你带狗出门散步时,如果这只狗是高度驯化的豺性犬,即便它没有受过训练,也会跟在你身边,无论它在你前方、后方,还是侧方,都会和你保持一定的距离,根据你的步伐调整自己的速度。它天性顺从,只要你叫它的名字,它就会过来,不是因为它想过来,也不是因为你哄它了,而是它知道自己必须过来。你的叫声越大,它过来得越快,可是如果你叫一只狼性犬,它根本不会过来,它总会在远处以友好的姿态,向你致意。

From #

所罗门王的指环

狗身上的豺性

Content #

比较行为学研究发现,所有的欧洲狗,包括体形庞大的大丹犬(Great Dane)和猎狼犬(Wolfhound),都是纯种的豺狗(Aursus),血液中包含着极少的狼的血缘。现有的最纯种的狼狗,特别是所谓的雪橇犬(Malemut)和哈士奇(Husky),都是美洲北极地区的品种。格陵兰的爱斯基摩犬(Esquimaux Dog)身上也只有一丝豺的特性,而欧亚大陆北极地区的品种,比如莱卜兰犬(Lapland Dog)、俄罗斯莱卡(Russian Lajkas)、萨摩耶(Samoyedes)和松狮犬的身上包含更多的豺性。不管怎样,后面提到的几种狗,身上更多地传承了祖先特征中狼的一面,它们颧骨都很高,眼睛是斜的,鼻子略微上翘,所以它们的面部表情很像狼。当然,松狮犬一身火红色的外衣,又毫无疑问地体现出血液中豺的一面。

From #

所罗门王的指环

多行删除命令(D)

Content #

单行删除(d)命令用来删除模式空间中的当前行。然而,如果和N命令一起使用,则必须小心: $ sed ‘N ; /System\nAdmin/d’ data4.txt All System Admins should attend. $ 单行删除命令会在不同的行中查找单词System和Admin,然后在模式空间中将两行都删掉。 sed编辑器提供了多行删除(D)命令,该命令只会删除模式空间中的第一行,即删除该行中的换行符及其之前的所有字符: $ sed ‘N ; /System\nAdmin/D’ data4.txt Admin group meeting will be held. All System Admins should attend. $ 文本的第二行虽然被N命令加入了模式空间,但仍然完好。如果需要删除目标数据字符串所在行的前一行,那么D命令就能派上用场了。

这里有个例子,它会删除数据流中出现在第一行之前的空行: $ cat data5.txt

Header Line First Data Line

End of Data Lines $ $ sed ‘/^$/{N ; /Header/D}’ data5.txt Header Line First Data Line

End of Data Lines $ sed编辑器脚本会查找空行,然后用N命令将下一行加入模式空间。如果模式空间中含有单词Header,则D命令会删除模式空间中的第一行。如果不结合使用N命令和D命令,则无法做到在不删除其他空行的情况下只删除第一个空行。

From #

Linux命令行与shell脚本编程大全

...

多行next(N)命令

Content #

单行next(n)命令会将数据流中的下一行移入sed编辑器的工作空间(称为模式空间)。多行版本的next(N)命令则是将下一行添加到模式空间中已有文本之后。

这样的结果是将数据流中的两行文本合并到同一个模式空间中。文本行之间仍然用换行符分隔,但sed编辑器现在会将两行文本当成一行来处理。

下面的例子演示了N命令的工作方式:

$ cat data2.txt
Header Line
First Data Line
Second Data Line
End of Data Lines
$
$ sed '/First/{ N ; s/\n/ / }' data2.txt
Header Line
First Data Line Second Data Line
End of Data Lines
$

sed编辑器脚本先查找含有单词First的那行文本,找到该行后,使用N命令将下一行与该行合并,然后用替换命令将换行符(\n)替换成空格。这样一来,两行文本在sed编辑器的输出中就成了一行。

如果要在数据文件中查找一个可能会分散在两行中的文本短语,那么这是一个很管用的方法。这里有个例子:

$ cat data3.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All System Admins should attend.
Thank you for your cooperation.
$
$ sed 's/System Admin/DevOps Engineer/' data3.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All DevOps Engineers should attend.
Thank you for your cooperation.
$

替换命令会在文本文件中查找特定的双词短语System Admin。如果短语是在一行中,那么事情就很好办,替换命令直接就能搞定。但如果短语分散在两行中,那么替换命令就没辙了。 N命令可以解决这个问题: $ sed ‘N ; s/System.Admin/DevOps Engineer/’ data3.txt On Tuesday, the Linux DevOps Engineer group meeting will be held. All DevOps Engineers should attend. Thank you for your cooperation. $ 用N命令将第一个单词所在行与下一行合并,即使短语内出现了换行,仍然可以查找到该短语。注意,替换命令在System和Admin之间用了点号模式(.)来匹配空格和换行符这两种情况。但如果点号匹配的是换行符,则删掉换行符会导致两行被合并成一行。这可能不是你想要的结果。要解决这个问题,可以在sed编辑器脚本中用两个替换命令,一个用来处理短语出现在多行中的情况,另一个用来处理短语出现在单行中的情况:

...

单行next(n)命令

Content #

单行next(n)命令会告诉sed编辑器移动到数据流中的下一行,不用再返回到命令列表的最开始位置。记住,通常sed编辑器在移动到数据流中的下一行之前,会在当前行中执行完所有定义好的命令,而单行next命令改变了这个流程。

在这个例子中,有一个包含5行文本的数据文件,其中有2行是空的。我们的目标是删除首行之后的空行,留下末行之前的空行。如果编写一个删除空行的sed脚本,那么结果是2个空行都会被删掉,这可不是我们想要的结果: $ cat data1.txt Header Line

Data Line #1

End of Data Lines $ $ sed ‘/^$/d’ data1.txt Header Line Data Line #1 End of Data Lines $ 由于要删除的行是空行,因此没有任何能够标示这种行的文本可供查找。解决办法是使用单行next命令。在这个例子中,先用脚本查找含有单词Header的那一行,找到之后,单行next命令会让sed编辑器移动到文本的下一行,也就是我们想删除的空行: $ sed ‘/Header/{n ; d}’ data1.txt Header Line Data Line #1

End of Data Lines $ 这时,sed编辑器会继续执行命令列表,即使用删除命令删除空行。sed编辑器在执行完命令脚本后会读取数据流中下一行文本,并从头开始执行脚本。因为sed 编辑器再也找不到包含单词Header的行了,所以也不会再有其他行被删除。

sed的n命令在执行时会依次做四件事,请问是哪四件?

  • print the current pattern space
  • clears the pattern space
  • reads the next line from the input-file into pattern space
  • resumes command execution where it left off

From #

Linux命令行与shell脚本编程大全

...

目录文件计数

Content #

shell脚本,它可以对PATH环境变量中各个目录所包含的文件数量进行统计。为此,需要将PATH环境变量解析成单独的目录名。 $ echo $PATH usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr games:/usr/ local/games $ 根据Linux系统中应用程序所处的位置,PATH环境变量也会有所不同。关键是要认识到,PATH中的各个路径由冒号分隔。要获取可在脚本中使用的目录列表,必须用空格替换冒号。现在你会发现,sed用一个简单的表达式就能完成替换工作: $ echo $PATH | sed ’s/:/ g' /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games $ 分离出目录之后,可以使用标准for语句来遍历每个目录: mypath=`echo $PATH | sed ’s:/ /g’` for directory in $mypath do … done 对于单个目录,可以用ls命令列出其中的文件,再用另一个for语句来遍历每个文件,对文件计数器增值。这个脚本的最终版本如下:

$ cat countfiles
#!/bin/bash
# count number of files in your PATH
mypath=$(echo $PATH | sed 's/:/ /g')
count=0
for directory in $mypath
do
   check=$(ls $directory)
   for item in $check
   do
         count=$[ $count + 1 ]
   done
   echo "$directory - $count"
   count=0
done
$ ./countfiles /usr/local/sbin - 0
/usr/local/bin - 2
/usr/sbin - 213
/usr/bin - 1427
/sbin - 186
/bin - 152
/usr/games - 5
/usr/local/games - 0
$

From #

Linux命令行与shell脚本编程大全

...

选项–re-interval

Content #

在默认情况下,gawk不识别正则表达式区间,必须指定gawk的命令行选项–re-interval才行。来看一个简单的单值区间的例子: $ echo “bt” | gawk –re-interval ‘/be{1}t/{print $0}’ $ $ echo “bet” | gawk –re-interval ‘/be{1}t/{print $0}’ bet $ echo “beet” | gawk –re-interval ‘/be{1}t/{print $0}’ $ 通过指定区间为1,限定了该字符应该出现的次数。如果该字符出现多次,那么模式匹配就不成立。很多时候,同时指定区间下限和上限也很方便: $ echo “bt” | gawk –re-interval ‘/be{1,2}t/{print $0}’ $ $ echo “bet” | gawk –re-interval ‘/be{1,2}t/{print $0}’ bet $ echo “beet” | gawk –re-interval ‘/be{1,2}t/{print $0}’ beet $ echo “beeet” | gawk –re-interval ‘/be{1,2}t/{print $0}’ $ 在这个例子中,字符e出现一次或两次,模式都能匹配;否则,模式无法匹配。

From #

Linux命令行与shell脚本编程大全

...

替换文件中的占位文本

Content #

读取命令还有一种很酷的用法是和删除命令配合使用,利用另一个文件中的数据来替换文件中的占位文本。假如你保存在文本文件中的套用信件如下所示: $ cat notice.std Would the following people: LIST please report to the ship’s captain. $ 套用信件将通用占位文本LIST放在了人物名单的位置。要在占位文本后插入名单,只需使用读取命令即可。但这样的话,占位文本仍然会留在输出中。为此,可以用删除命令删除占位文本,其结果如下: $ sed ‘/LIST/{ > r data12.txt > d > }’ notice.std Would the following people: Blum, R Browncoat McGuiness, A Alliance Bresnahan, C Browncoat Harken, C Alliance please report to the ship’s captain. $ 现在占位文本已经被替换成了数据文件中的名单。

From #

Linux命令行与shell脚本编程大全

读取文件命令(r)

读取文件命令(r)

Content #

读取(r)命令允许将一条独立文件中的数据插入数据流。读取命令的格式如下所示:

[address]r filename

filename参数指定了数据文件的绝对路径或相对路径。读取命令中无法使用地址区间,只能指定单个行号或文本模式地址。sed编辑器会将文件内容插入指定地址之后。 $ cat data13.txt This is an added line. This is a second added line. $ $ sed ‘3r data13.txt’ data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is an added line. This is a second added line. This is the 4th line. $ sed编辑器会将数据文件中的所有文本行都插入数据流。在使用文本模式地址时,同样的方法也适用: $ sed ‘/number 2/r data13.txt’ data6.txt This is line number 1. This is line number 2. This is an added line. This is a second added line. This is the 3rd line. This is the 4th line. $ 要在数据流的末尾添加文本,只需使用美元符号地址即可: $ sed ‘$r data13.txt’ data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. This is an added line. This is a second added line. $

...

写入文件命令(w)

Content #

写入(w)命令用来向文件写入行。该命令格式如下所示:

[address]w filename

filename可以使用相对路径或绝对路径,但不管使用哪种,运行sed编辑器的用户都必须有文件的写权限。地址可以是sed支持的任意类型的寻址方式,比如单个行号、文本模式、行区间或文本模式区间。

下面的例子会将数据流中的前两行写入文本文件: $ sed ‘1,2w test.txt’ data6.txt This is line number 1. This is line number 2. This is the 3rd line. This is the 4th line. $ $ cat test.txt This is line number 1. This is line number 2. $ 当然,如果不想在STDOUT中显示文本行,可以使用sed命令的-n选项。如果要根据一些公用的文本值,从主文件(比如下面的邮件列表)中创建一份数据文件,则使用写入命令会非常方便: $ cat data12.txt Blum, R Browncoat McGuiness, A Alliance Bresnahan, C Browncoat Harken, C Alliance $ $ sed -n ‘/Browncoat/w Browncoats.txt’ data12.txt $ $ cat Browncoats.txt Blum, R Browncoat Bresnahan, C Browncoat $ sed编辑器会将匹配文本模式的数据行写入目标文件。

...