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> #[email protected].
</email> and email address, blog "http://www.google.com",
[email protected] dfdfdfdddfdf;[email protected]<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
[email protected]
[email protected]
[email protected]

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章