Linux基础学习笔记(十二)——管道命令
文章目錄
- 前言
- 管道命令
- cut命令
- sort,wc,uniq命令
- sort命令
- uniq命令
- wc命令
- 雙向重定向——tee命令
- 字符替換命令
- tr命令
- col命令
- join命令
- paste命令
- expand命令
- 文件拆分命令
- 參數替換
- 關于-
- 總結
前言
上一篇博客簡述了一下Linux中的輸入輸出重定向,這篇博客總結一下Linux中的管道命令,為后面的文件格式化,shell學習做一個基礎,對應《鳥哥的Linux私房菜》第十章10.6的內容
管道命令
其實管道命令,就是使用|這個界定符號,這個命令默認僅能處理經由前一個指令傳過來的正確信息,也就是上一篇博客中提到的standard output信息,對于standard error 標準錯誤信息,默認是沒法處理的。
如果想要管道命令之后的某個命令,可以處理標準錯誤輸出,可以將標準輸出和標準錯誤輸出均重定向到一處,這個在上一篇博客中有介紹,這里不做說明了。
下面總結的命令,是在管道命令的基礎上進行一些數據處理
cut命令
主要用于數據的截取,從列的角度進行數據截取,上一篇博客中的grep命令是從行的角度過濾數據。
實例
##將export輸出的結果,從第12個字符開啟截取,一直截取到末尾,輸出結果 [root@localhost shell-learn]# export | cut -c 12- CLASSPATH=".:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jar" HISTCONTROL="ignoredups" HISTSIZE="1000" HOME="/root" HOSTNAME="localhost.localdomain" JAVA_HOME="/usr/local/software/java/jdk1.8.0_191" LANG="zh_CN.UTF-8" LESSOPEN="||/usr/bin/lesspipe.sh %s" LOGNAME="root" ###...以下輸出結果省略 # 用如下命令,可以達到同等效果 [root@localhost shell-learn]# export | cut -d ' ' -f 3 CLASSPATH=".:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jar" HISTCONTROL="ignoredups" HISTSIZE="1000" HOME="/root" ###...以下輸出結果省略##從last命令的輸出結果中,截取登錄的用戶名 [root@localhost shell-learn]# last | cut -d ' ' -f 1 reboot root reboot root ###...以下輸出結果省略sort,wc,uniq命令
sort命令
sort可以幫我們進行數據的排序,而且可以根據不同的數據形態來排序
如果要詳細探討每一個命令屬性,這個就有點麻煩了,《鳥哥的Linux私房菜》也只介紹了簡單的幾個實例
## 讀取個人賬號信息數據,并排序,默認按第一個數據來排序 [root@localhost shell-learn]# cat /etc/passwd | sort adm:x:3:4:adm:/var/adm:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin esuser:x:1001:1001::/home/esuser:/bin/bash ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin halt:x:7:0:halt:/sbin:/sbin/halt ###...以下輸出結果省略##讀取個人賬號信息數據,并以第三列數據進行排序 ### -t指定分割符,-k指定分割之后的排序字段 [root@localhost shell-learn]# cat /etc/passwd | sort -t ':' -k 3 root:x:0:0:root:/root:/bin/bash esuser:x:1001:1001::/home/esuser:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin ###...以下輸出結果省略 ## 可以看到上面的結果11 排在1001之后,這沒按照數字排序,如果按照數字排序,需要指定-n選項 [root@localhost shell-learn]# cat /etc/passwd | sort -t ':' -k 3 -n root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin ###...以下輸出結果省略## 通過last讀取登錄數據,按照列切分之后,得到登錄賬號數據,并排序 [root@localhost shell-learn]# last | cut -d ' ' -f1 | sort reboot ###...以下輸出結果省略uniq命令
類似SQL語句中的distinct,這里是對排序之后的結果進行去重
實例
## 通過last命令讀取登錄信息,并根據空格進行分割,然后讀取登錄賬號,排序,去重。 [root@localhost shell-learn]# last | cut -d ' ' -f1 | sort | uniq ##輸出結果 reboot root wtmp ## 通過last命令讀取登錄信息,并根據空格進行分割,然后讀取登錄賬號,排序,去重,并統計登錄次數,類似SQL中的count。 [root@localhost shell-learn]# last | cut -d ' ' -f1 | sort | uniq -c1 65 reboot87 root1 wtmpwc命令
wc命令用于統計文件里頭多少字符,多少行,多少字符信息。
實例
# 讀取man_db.conf中的數據,并進行字符統計 # 輸出的三個結果中,分別表示[行,字數,字符數] [root@localhost shell-learn]# cat /etc/man_db.conf | wc131 723 5171 # 讀取last命令中登入系統的總人數 ##這里通過grep -v命令,去除了很多無用的登錄記錄信息 [root@localhost shell-learn]# last | grep [a-zA-Z] |grep -v 'wtmp' | grep -v 'reboot' | \ > grep -v 'unknown' | wc -l 87 # 讀取當前系統中有多少個賬戶 [root@localhost shell-learn]# cat /etc/passwd | wc -l 21雙向重定向——tee命令
之前我們在利用重定向命令輸出的時候,將數據流重定向到某個文件之后,屏幕的標準輸出就木有了,tee命令可以將數據流分送到文件和屏幕
實例
#使用tee命令之后,可以將標準輸出備份到文件的同時,也不影響數據流后續的標準輸出 ## 該命令執行完成之后,last.txt中會存有一份last命令的標準輸出,后面的cut也能得到正常結果 [root@localhost shell-learn]# last | tee last.txt | cut -d ' ' -f1字符替換命令
除了使用dos2unix和unix2dox來進行換行符的轉換之外,linux還提供了其他字符轉換的命令
tr命令
用來刪除信息中的一些文件或者進行文字替換
實例
# 將last命令的輸出結果中,小寫字母轉成大寫字母 [root@localhost shell-learn]# last | tr '[a-z]' '[A-Z]' ROOT PTS/0 192.168.0.103 SUN JUL 31 09:53 STILL LOGGED IN ROOT TTY1 SUN JUL 31 09:53 STILL LOGGED IN REBOOT SYSTEM BOOT 3.10.0-1160.EL7. SUN JUL 31 09:52 - 11:31 (01:38) ###...以下輸出結果省略 ## 將cat /etc/passwd命令的輸出結果中的冒號刪除 [root@localhost shell-learn]# cat /etc/passwd | tr -d ':' rootx00root/root/bin/bash binx11bin/bin/sbin/nologin daemonx22daemon/sbin/sbin/nologin ###...以下輸出結果省略col命令
這個命令用來簡單的將tab鍵替換成空格
實例
#cat -A顯示所有特殊字符,col -x 將tab替換成空格,最后的more命令顯示的內容沒有^I字符 [root@localhost shell-learn]# cat /etc/man_db.conf | col -x | cat -A | morejoin命令
類似SQL中的join,如果兩個文件中的數據列相同,則通過join命令只輸出一列
實例
# 通過head命令查看,/etc/passwd和/etc/shadow兩個文件中的第一列是相同的 [root@localhost shell-learn]# head -n 3 /etc/passwd /etc/shadow ==> /etc/passwd <== root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin==> /etc/shadow <== root:$6$FI.UzpVEoa1js0tM$j2khNaltnlIWqz7/aXd7scHOIrwJiVxIh.df9Da1gMQYdxBXL1O6odGDZNhjfMSfxb1u39jGXQ6/.o1f0duRS0::0:99999:7::: bin:*:18353:0:99999:7::: daemon:*:18353:0:99999:7::: #通過join命令查詢之后,第一列只顯示一次 [root@localhost shell-learn]# join -t ':' /etc/passwd /etc/shadow | head -n 3 root:x:0:0:root:/root:/bin/bash:$6$FI.UzpVEoa1js0tM$j2khNaltnlIWqz7/aXd7scHOIrwJiVxIh.df9Da1gMQYdxBXL1O6odGDZNhjfMSfxb1u39jGXQ6/.o1f0duRS0::0:99999:7::: bin:x:1:1:bin:/bin:/sbin/nologin:*:18353:0:99999:7::: daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:18353:0:99999:7:::# /etc/passwd中的第四列和/etc/group文件中的第三列內容是一致的 [root@localhost shell-learn]# head -n 3 /etc/passwd /etc/group ==> /etc/passwd <== root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin==> /etc/group <== root:x:0: bin:x:1: daemon:x:2: # 通過join指定匹配的列,-1指定第一個文件要匹配的列,-2指定第二個文件要匹配的列 [root@localhost shell-learn]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3 0:root:x:0:root:/root:/bin/bash:root:x: 1:bin:x:1:bin:/bin:/sbin/nologin:bin:x: 2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:需要特別注意的是,在使用join之前,數據最好已經經過排序
paste命令
paste命令比join命令要簡單,paste是直接將兩行數據貼在一起,中間tab鍵隔開,不管這兩行數據中是否有可匹配的字段
實例
## 將/etc/passwd /etc/shadow文件同一行拼接在一起,并顯示前三行 [root@localhost shell-learn]# paste /etc/passwd /etc/shadow | head -n 3 root:x:0:0:root:/root:/bin/bash root:$6$FI.UzpVEoa1js0tM$j2khNaltnlIWqz7/aXd7scHOIrwJiVxIh.df9Da1gMQYdxBXL1O6odGDZNhjfMSfxb1u39jGXQ6/.o1f0duRS0::0:99999:7::: bin:x:1:1:bin:/bin:/sbin/nologin bin:*:18353:0:99999:7::: daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:18353:0:99999:7:::expand命令
將tab鍵的字符轉成空格符
實例
#從man_db.conf文件中,以MANPATH開頭的數據 [root@localhost shell-learn]# grep '^MANPATH' /etc/man_db.conf | head -n 3 MANPATH_MAP /bin /usr/share/man MANPATH_MAP /usr/bin /usr/share/man MANPATH_MAP /sbin /usr/share/man ##tab鍵的符號,在cat -A之后,通過^I顯示出來 [root@localhost shell-learn]# grep '^MANPATH' /etc/man_db.conf | head -n 3 | cat -A MANPATH_MAP^I/bin^I^I^I/usr/share/man$ MANPATH_MAP^I/usr/bin^I^I/usr/share/man$ MANPATH_MAP^I/sbin^I^I^I/usr/share/man$ ## 這里設定的是6個字符代表一個tab符號 [root@localhost shell-learn]# grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 | cat -A MANPATH_MAP /bin /usr/share/man$ MANPATH_MAP /usr/bin /usr/share/man$ MANPATH_MAP /sbin /usr/share/man$文件拆分命令
split命令是linux中的文件拆分命令
實例
[root@localhost shell-learn]# cd /tmp ##指定以300k的大小進行文件拆分,前綴為services [root@localhost tmp]# split -b 300k /etc/services services [root@localhost tmp]# ll 總用量 656 -rw-r--r--. 1 root root 307200 7月 31 14:33 servicesaa -rw-r--r--. 1 root root 307200 7月 31 14:33 servicesab -rw-r--r--. 1 root root 55893 7月 31 14:33 servicesac ## 將上述三個文件,合并為一個文件 使用數據流重定向即可完成 [root@localhost tmp]# cat services* >> servicesback [root@localhost tmp]# ll 總用量 1312 -rw-r--r--. 1 root root 307200 7月 31 14:33 servicesaa -rw-r--r--. 1 root root 307200 7月 31 14:33 servicesab -rw-r--r--. 1 root root 55893 7月 31 14:33 servicesac -rw-r--r--. 1 root root 670293 7月 31 14:36 servicesback ## 將 ls -al /的輸出信息,每10行記錄生成一個文件 [root@localhost tmp]# ls -al / | split -l 10 - lssplitfile [root@localhost tmp]# wc -l lssplitfile*10 lssplitfileaa10 lssplitfileab5 lssplitfileac25 總用量參數替換
xargs是管道命令中,控制傳遞個下一個命令的參數個數
實例
#正常的id命令可以顯示用戶組別等詳細信息 [root@localhost tmp]# id uid=0(root) gid=0(root) 組=0(root) 環境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 [root@localhost tmp]# id root uid=0(root) gid=0(root) 組=0(root) ## 可以通過截取/etc/passwd文件得到用戶信息 [root@localhost tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 root bin daemon # 是否可以直接通過管道,將這里兩個命令結合,達到輸出所有用戶組別信息的目的? ##取出了三個,但是只有一個,因為前面的命令輸出了三個用戶,但是id只能接受一個參數,下述指令相當于只執行了id [root@localhost tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | id uid=0(root) gid=0(root) 組=0(root) 環境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023##換一種姿勢也不行 [root@localhost tmp]# id $(cut -d ':' -f 1 /etc/passwd | head -n 3) id: 額外的操作數 "bin" Try 'id --help' for more information.##通過xargs指示傳遞給下一個命令的那參數,一個一個的給。可以得到正確結果 [root@localhost tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id uid=0(root) gid=0(root) 組=0(root) uid=1(bin) gid=1(bin) 組=1(bin) uid=2(daemon) gid=2(daemon) 組=2(daemon) #加上 -p 選項,每次都會詢問用戶是否確認執行 [root@localhost tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id id root ?...y uid=0(root) gid=0(root) 組=0(root) id bin ?...y uid=1(bin) gid=1(bin) 組=1(bin) id daemon ?...y uid=2(daemon) gid=2(daemon) 組=2(daemon) #將所有/etc/passwd內的賬號都以id進行查閱,但差到sync就結束 [root@localhost tmp]# cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -e'sync' -n 1 id uid=0(root) gid=0(root) 組=0(root) uid=1(bin) gid=1(bin) 組=1(bin) uid=2(daemon) gid=2(daemon) 組=2(daemon)xargs是一個比較好用的工具,可以將原來本身不支持管道命令的操作一起級聯起來。
關于-
在管道命令中,有時候會出現-這是因為,有時候管道命令會使用到前一個指令的標準輸出作為本地的輸入,但是這個時候用文件作為中轉有些不方便,因此 - 其實就代表命令的標磚輸出。
# 例如:我們要打包一個文件夾/var/log到當前目錄下通常分為兩步 tar -cvf log.tar /var/log/ zip -r log.tar.zip log.tar rm -rf log.tar # 寫成一條語句 tar -cvf log.tar /var/log/ && zip -r log.tar.zip log.tar && rm -rf log.tar ## 可以看到第一條語句的log.tar就是第二條語句的輸入,可以用 - 來取代這個輸入 tar -cvf – /var/log | zip -r log.zip -總結
起于管道命令,基于管道命令總結了一堆結合管道命令的實例
總結
以上是生活随笔為你收集整理的Linux基础学习笔记(十二)——管道命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序和webview如何通信?
- 下一篇: linux 其他常用命令