cut命令:查找符合條件的列
cut 命令是在文件中提取符合條件的列,雖然 cut 命令用於提取符合條件的列,但是也要一行一行地進行數據提取。也就是說,先要讀取文本的第一行數據,在此行中判斷是否有符合條件的字段,然后再處理第二行數據。我們也可以把 cut 成為字段提取命令。命令格式如下:
[root@localhost ~]# cut [選項] 文件名
選項:
- -f 列號:提取第幾列;
- -d 分隔符:按照指定分隔符分割列;
- -c 字符范圍:不依賴分隔符來區分列,而是通過字符范圍(行首為 0)來進行字段提取。"n-"表示從第 n 個字符到行尾;"n-m"表示從第 n 個字符到第 m 個字符;"-m"表示從第 1 個字符到第 m 個字符;
cut命令示例
cut 命令的默認分隔符是制表符,也就是 Tab 鍵。我們先建立一個測試文件,然后看看 cut 命令的作用。
[root@localhost ~]# vi student.txt ID Name gender Mark 1 Liming M 86 2 Sc M 90 3 Gao M 83
建立學員成績表,注意這張表中所有的分隔符都是制表符,不能是空格,否則后面的實驗會出現問題。
先看看 cut 命令該如何使用:
[root@localhost ~]# cut -f 2 student.txt #提取第二列的內容 Name Liming Sc Gao
如果想要提取多列,將列號直接用","隔開,命令如下:
[root@localhost ~]# cut -f 2,3 student.txt #提取第二列和第三列的內容 Name gender Liming M Sc M Gao M
cut 命令可以按照字符進行提取。需要注意的是,"8-"代表提取所有行從第 8 個字符到行尾,而"10-20"代表提取所有行的第 10~20 個字符,而"-8"代表提取所有行從行首到第 8 個字符,命令如下:
[root@localhost ~]#cut-c 8- student.txt #提取取每行從第8個字符到行尾,好像很亂啊,那是因為每行的字符個數不相等 gender Mark g M 86 90 83
當然,cut 命令也可以手工指定分隔符。例如,我想看看當前 Linux 服務器中有哪些用戶、用戶的 UID 時,就可以這樣操作:
[root@localhost ~]# cut -d ":" -f 1,3 /etc/passwd #以":"作為分隔符,提取/etc/passwd文件的第一列和第三列 root:0 bin:1 daemon:2 adm:3 lp:4
cut 命令很方便,不過最主要的問題是對空格識別得不好,很多命令的輸出格式中都不是制表符,而是空格符,比如:
[root@localhost ~]# df #統計分區使用狀況 文件系統 1K-塊 已用 可用 已用% 掛載點 /dev/sda3 19923216 1848936 17062212 10% / tmpfs 312672 0 312672 0% /dev/shm /dev/sda1 198337 26359 161738 15% /boot /dev/srO 3626176 3626176 0 100% /mnt/cdrom
如果想用 cut 命令截取第一列和第三列,就會出現這樣的情況:
[root@localhost ~]# df -h|cut -d""-f 1,3 文件系統 /dev/sda3 tmpfs /dev/sda1 /dev/sr0
因為 df 命令輸出的分隔符不是制表符,而是多個空格符,所以 cut 命令會將每個空格符當作一個分隔符,而這樣數,第三列剛好也是空格,所以輸出才會是上面這種情況。
總之,cut 命令不能很好地識別空格符。如果想要以空格符作為分隔符,建議使用 awk 命令。
printf命令:格式化輸出
print 會在每個輸出之后自動加入一個換行符;而 printf 是標准格式輸出命令,並不會自動加入換行符,如果需要換行,則需要手工加入換行符。在 awk 中可以識別 print 輸出動作和 printf 輸出動作,但是在 Bash 中只能識別標准格式化輸出命令 printf。printf 命令格式如下:
[root@localhost ~]# printf '輸出類型輸出格式' 輸出內容
輸出類型:
- %ns:輸出字符串。n 是數字,指輸出幾個字符;
- %ni:輸出整數。n 是數字,指輸出幾個數字‘’
- %m.nf: 輸出浮點數。m 和 n 是數字,指輸出的整數位數和小數位數。如 %8.2f 代表共輸出 8 位數,其中 2 位是小數,6 位是整數;
輸出格式:
- \a: 輸出警告聲音;
- \b:輸出退格鍵,也就是 Backspaced 鍵;
- \f:清除屏幕;
- \n:換行;
- \r:回車,也就是 Enter 鍵;
- \t:水平輸出退格鍵,也就是 Tab 鍵;
- \v:垂直輸出退格鍵,也就是 Tab 鍵;
printf命令示例
創建 student.txt 文件。文件內容如下:
[root@localhost ~]# vi student.txt ID Name PHP Linux MySQL Average 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
使用 printf 命令輸出這個文件的內容,如下:
[root@localhost ~]# printf '%s' $(cat student.txt) IDNamegenderPHPUnuxMySQl_Average1LjmingM82 958687.662ScM74968785.663GaoM998393 91.66
printf 命令如果不指定輸出格式,則會把所有輸出內容連在一起輸出。其實文本的輸出本身就是這樣的,cat 等文本輸出命令之所以可以按照格式漂亮地輸出,那是因為 cat 命令已經設定了輸出格式。
那么,為了用 printf 輸出合理的格式,應該這樣做:
[root@localhost ~]# printf '%s\t %s\t %s\t %s\t %s\t %s\t\n' $(cat student.txt) #注意:在printf命令的單引號中只能識別格式輸出符號,而手工輸入的空格是無效的 ID Name PHP Linux MySQL Average 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
在 printf 命令的單引號中輸入的任何空格都不會反映到格式輸出中,只有格式輸出符號才能影響 printf 命令的輸出結果。
因為我們的文檔有6列,所以使用 6 個"%s"代表這 6 列字符串,每個字符串之間用"\t"分隔;最后還要加入"\n",使得每行輸出都換行,否則這些數據還是會連成一行的。
如果不想把成績當成字符串輸出,而是按照整型和浮點型輸出,則要這樣做:
[root@localhost ~]# printf '%i\t %s\t %i\t %i\t %i\t %8.2f\t\n'\ $(cat student.txt | grep -v Name) 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
先解釋"cat student.txt|grep -v Name"這條命令。這條命令會把第一行標題取消,剩余的內容才用 printf 格式化輸出。在剩余的內容中,第 1、3、4、5 列為整型,所以用"%i"輸出;而第 2 列是字符串,所以用"%s"輸出;而第 6 列是小數,所以用"%8.2f"輸出。"%8.2f"代表可以輸出 8 位數,其中有 2 位是小數,有 6 位是整數。