一、按列合併多個文件
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