Linux_Shell脚本学习第四章-让文本飞(下)

一、按列合并多个文件

1.1 paste

$ paste file1 file2 file3 ...

例:

$ cat file1.txt
1
2
3
4
5
$ cat file2.txt
slynux
gnu
bash
hack
$ paste file1.txt file2.txt
1 slynux
2 gnu
3 bash
4 hack
5

默认的分隔符是制表符,也可以用-d指定分隔符:

$ paste file1.txt file2.txt -d ","
1,slynux
2,gnu
3,bash
4,hack
5,

二、打印文件或行中的第n 个单词或列

2.1 打印第5列:

$ awk '{ print $5 }' filename

2.2 可以打印多列数据并在各列间插入指定的字符串

如果要打印当前目录下各文件的权限和文件名,可以使用下列命令:

$ ls -l | awk '{ print $1 " : " $8 }'
-rw-r--r-- : delimited_data.txt
-rw-r--r-- : obfuscated.txt
-rw-r--r-- : paste1.txt
-rw-r--r-- : paste2.txt

三、打印指定行或模式之间的文本

我们有时候可能需要根据某些条件打印文件的一部分,比如由指定行号或起止模式所匹配的文本范围。

3.1 打印从M行到N行之间的文本

$ awk 'NR==M, NR==N' filename

3.2 打印位于模式start_pattern与end_pattern之间的文本

$ awk '/start_pattern/, /end_pattern/' filename

例如:

$ cat section.txt
line with pattern1
line with pattern2
line with pattern3
line end with pattern4
line with pattern5
$ awk '/pa.*3/, /end/' section.txt
line with pattern3
line end with pattern4

awk中使用的模式为正则表达式。

四、以逆序形式打印行

4.1 tac

tac file1 file2 ...

例如

$ seq 5 | tac
5
4
3
2
1

tac命令默认使用\n作为行分隔符。但我们也可以用选项-s指定其他分隔符。

$ echo "1,2" | tac-s,
2
1

4.1 awk

seq 9 | \
awk '{ lifo[NR]=$0 } \
END { for(lno=NR;lno>-1;lno--){ print lifo[lno]; }
}'

五、解析文本中的电子邮件地址和URL

5.1 匹配电子邮件地址

能够匹配电子邮件地址的正则表达式如下:

[A-Za-z0-9._]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}

例如

$ cat url_email.txt
this is a line of text contains,<email> #slynux@slynux.com.
</email> and email address, blog "http://www.google.com",
test@yahoo.com dfdfdfdddfdf;cool.hacks@gmail.com<br />
<a href="http://code.google.com"><h1>Heading</h1>

因为用到了扩展正则表达式(例如+),所以得使用egrep命令:

$ egrep -o '[A-Za-z0-9._]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}' url_email.txt
slynux@slynux.com
test@yahoo.com
cool.hacks@gmail.com

5.2 匹配HTTP URL

匹配HTTP URL的egrep正则表达式如下:

http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}

例如:

$ egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}" url_email.txt
http://www.google.com
http://code.google.com

六、删除文件中包含特定单词的句子

先创建一个包含替换文本的文件。例如:

$ cat sentence.txt
Linux refers to the family of Unix-like computer operating systems
that use the Linux kernel. Linux can be installed on a wide variety
of computer hardware, ranging from mobile phones, tablet computers
and video game consoles, to mainframes and supercomputers. Linux is
predominantly known for its use in servers.

我们的目标是删除包含mobile phones的句子。可以用下面的sed语句来实现

$ sed 's/ [^.]*mobile phones[^.]*\.//g' sentence.txt
Linux refers to the family of Unix-like computer operating systems
that use the Linux kernel. Linux is predominantly known for its use
in servers.

sed的正则表达式s/ [^.]mobile phones[^.].//g采用的格式为s/substitution_pattern/replacement_string/g。它将与substitution_pattern相匹配的每一处内容都用replacement_string替换掉。

本例中的substitution_pattern是用来匹配整句文本的正则表达式。文件中的每一句话都是以空格开头,以.结尾。正则表达式要匹配内容的格式就是:空格+若干文本+需要匹配的字符串+若干文本+句点。一个句子中除了作为分隔符的句点之外,可以包含任意字符。因此需要使用[^.],该模式可以匹配除句点之外的任意字符。表示之前的字符可以出现任意多次。用来匹配文本的mobile phones被放置在两个 [^.] 之间。每一个匹配的句子均被//替换(注意,/与/之间没有任何内容)。

七、对目录中的所有文件进行文本替换

假设我们希望将所有.cpp文件中的Copyright替换成Copyleft:

find . -name *.cpp -print0 | xargs -I{} -0 sed -i 's/Copyright/Copyleft/g' {}

我们使用find命令在当前目录(.)下查找所有的.cpp文件。它使用-print0打印出以\0作为分隔符的文件列表(这可以避免文件名中的空格所带来的麻烦)。然后使用管道将文件列表传递给xargs,后者将文件名作为sed的参数,通过sed修改文件内容。

find有一个选项-exec,它可以对查找到的每个文件执行命令。我们可以使用该选项实现同样的效果或是改用下列命令

$ find . -name *.cpp -exec sed -i 's/Copyright/Copyleft/g' \{\} \;

八、文本切片与参数操作

替换变量内容中的部分文本

$ var="This is a line of text"
$ echo ${var/line/REPLACED}
This is a REPLACED of text"

单词line被替换成了REPLACED。

我们可以通过指定字符串的起始位置和长度来生成子串,其语法如下

${variable_name:start_position:length}

下面的命令可以打印出第5个字符之后的内容:

$ string=abcdefghijklmnopqrstuvwxyz
$ echo ${string:4}
efghijklmnopqrstuvwxyz

从第5个字符开始,打印8个字符:

$ echo ${string:4:8}
efghijkl

字符串起始字符的索引从0开始。从后向前计数,字符串末尾字符的索引为-1。如果-1出现在括号内,那么(-1)表示的就是最后一个字符的索引:

echo ${string:(-1)}
z
$ echo ${string:(-2):2}
yz
©️2020 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值