linux(5)--補充(管道| / 重定向> / xargs)/find 與xargs結合使用/vi,grep,sed,awk(支持正則表達式的工具程序)


本節中正則表達式的工具程序 grep,sed和awk是重點,也是難點!!!

先補充一下
一. 管道| / 重定向> / xargs
如:
1. 管道和重定向的區別:具體可以見 http://www.cnblogs.com/chengmo/archive/2010/10/21/1856577.html
以此為例: cat test.sh test1.sh 2>/dev/null | grep -n 'echo' 
此時若test.sh 不存在,報錯信息不會輸出到屏幕中,而是轉入 /dev/null中,如果不存在標准錯誤重定向 2>,則錯誤信息會顯示到屏幕中,重定向主要用於對標准輸入輸出的處理,控制輸出的路徑是屏幕還是寫入到標准文件中,
管道主要是用於接收輸入的內容並進行操作處理。而且作用接收標准輸入的命令才可以用作管道右邊。否則傳遞過程中數據會拋棄。 常用來作為接收數據管道命令有:sed,awk,cut,head,top,less,more,wc,join,sort,split 等等,都是些文本處理命令

2. xargs是產生某個命令的參數,即把 | 讀入的stdin的內容作為參數,傳遞給后面的命令
為什么要有xargs?
xargs了:
正常情況下,linux中的很多命令和工具,比如grep和awk,是可以通過管道,獲得內容,當做輸入參數的
但是對於cp,echo等命令,不識別從(終端中的)標准輸入所獲得的內容,而識別,命令后面的內容的,當做參數。
且Linux 2.6.23之前,任意長(足夠長,太長)的參數命令,是無法輸入到命令中的
所以,才有了xargs:將(足夠長的,太長的)輸入,分割成一個參數子列表,子列表中的參數,長度就很短,就可以被接受了。
常用格式:
| xargs -參數 ( 文件) 命令
(1)-0 :當sdtin含有特殊字元時候,將其當成一般字符,像/'空格等
$ echo "/ /  "|xargs -0 echo
/ /  
(2)-a file 從文件中讀入作為sdtin
$ xargs -a 1.txt echo
yuanyuan
(3)-e flag ,注意有的時候可能會是-E,flag必須是一個以空格分隔的標志,當xargs分析到含有flag這個標志的時候就停止。
$ cat 1.txt |xargs -E 'ddd' echo
aaa bbb ccc
(4)-n num 后面加次數,表示命令在執行的時候一次用的argument的個數,默認是用所有的。
$ cat 1.txt |xargs -n 2 echo
aaa bbb
ccc ddd
a b
(5)-p 操作具有可交互性,每次執行comand都交互式提示用戶選擇,當每次執行一個argument的時候詢問一次用戶
$ cat 1.txt |xargs -p echo
echo aaa bbb ccc ddd a b ?...y
aaa bbb ccc ddd a b
$ cat 1.txt |xargs -p echo
echo aaa bbb ccc ddd a b ?...n
(6)-t 表示先打印命令,然后再執行。
$ cat 1.txt |xargs -t echo
echo aaa bbb ccc ddd a b 
aaa bbb ccc ddd a b
(7)-i 或者是-I,這得看linux支持了,將xargs的每項名稱,一般是一行一行賦值給{},可以用{}代替,注意,-I 必須指定替換字符 -i 是否指定替換字符-可選
[yuanyuan@localhost Desktop]$ ls *.txt |xargs -t -i mv {} {}.bak
mv c.txt c.txt.bak
mv don.txt don.txt.bak
(8)-r  no-run-if-empty 如果沒有要處理的參數傳遞給xargsxargs 默認是帶 空參數運行一次,如果你希望無參數時,停止 xargs,直接退出,使用 -r 選項即可,其可以防止xargs 后面命令帶空參數運行報錯。
$ echo ""|xargs -t mv
mv 
mv: missing file operand
Try `mv --help' for more information.
(9)-d delim 分隔符,默認的xargs分隔符是回車,argument的分隔符是空格,這里修改的是xargs的分隔符
$ cat 1.txt.bak 
aaa@ bbb ccc@ ddd
a b
$ cat 1.txt.bak |xargs  -d '@' echo
aaa  bbb ccc  ddd
a b

find與xrags
$find . -name "install.log" -print | cat
./install.log                                                 #顯示從管道傳來的內容,僅僅作為字符串來處理
$find . -name "install.log" -print | xargs cat
aaaaaa                                                      #將管道傳來的內容作為文件,交給cat執行。也就是說,該命令執行的是如果存在install.log,那么就打印出這個文件的內容。
1、在當前目錄下查找所有用戶具有讀、寫和執行權限的文件,並收回相應的寫權限:
# find . -perm -7 -print | xargs chmod o-w
2、查找系統中的每一個普通文件,然后使用xargs命令來測試它們分別屬於哪類文件
# find . -type f -print | xargs file
./liyao: empty
3、嘗試用rm 刪除太多的文件,你可能得到一個錯誤信息:/bin/rm Argument list too long. 用xargs 去避免這個問題
$find ~ -name ‘*.log’ -print0 | xargs -i -0 rm -f {}
4、查找所有的jpg 文件,並且壓縮它
# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
5、拷貝所有的圖片文件到一個外部的硬盤驅動 
# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory


二. 正則表達式
用特殊字符的排列用來搜索/刪除/替換一行或多行字符,支持正則表達式的工具程序,vi,grep,sed,awk
正則表達式常用在郵件服務器中用於刪除垃圾郵件。


1.grep(查找有相關字符串的,顯示該行)
grep全稱是Global Regular Expression Print,表示全局正則表達式版本,它的使用權限是所有用戶
grep [cinvs] '搜索的字符串 ' filename
(1)主要參數
-a :二進制文本中,以文本文件的方式搜索結果
-c:只輸出匹配行的計數。
-i:不區分大小寫(只適用於單字符)。
-n:顯示匹配行及行號。
-s:不顯示不存在或無匹配文本的錯誤信息。
-v:反向選擇,顯示不包含匹配文本的所有行。
(2)搜索的字符串常用的正則表達式:
\  :轉義字符,忽略正則表達式中特殊字符的原有含義。
^ :匹配以某個字符串開始的行。
$ : 匹配以某個字符串結束的行。
\<:從匹配正則表達式的行開始。
\>:到匹配正則表達式的行結束。
[ ]:在[]內個某單個字符,如[A]即A符合要求 。
[ - ] :屬於[ - ]所標記的范圍字符,如[A-Z],即A、B、C一直到Z都符合要求 。
.  :表示一定有1個任意字符。
* :重復前面0個或多個字符。
例:
(1)[yuanyuan@localhost Desktop]$ grep "find" sw //顯示有find的行
find: `yxy': No such file or directory
[yuanyuan@localhost Desktop]$ grep -v "find" sw //不顯示有find的行
./yy/y
[yuanyuan@localhost Desktop]$ grep -in 'find' sw //顯示行號不區分大小寫
2:find: `yxy': No such file or directory
3:FIND YOU
如何更改文件的語系?
LANG=en
export LANG
(2)用[ ]代表集合字符(只是其中一個)
如:
[yuanyuan@localhost Desktop]$ grep -n [^7]huhu sw //^在[ ]內代表反向選擇,在[ ]外代表以..開頭,如[^a-z]即不是字母
7:huhuhuhuhu1huhu
[yuanyuan@localhost Desktop]$ grep -n [1-6]huhu sw //[ ]代表范圍在1-6的某一個數字。[0-9][a-z][A-Z],或[a-zA-Z0-9]
7:huhuhuhuhu1huhu
(3)行首與行尾字符(^與$)
如:
[yuanyuan@localhost Desktop]$ grep -v '^$' sw | grep -v '^#' //去掉空白行,且不以#開頭的
./yy/y
find: `yxy': No such file or directory
FIND YOU
fww1
f8fj8
huhu7huhu
huhuhuhuhu1huhu

[yuanyuan@localhost Desktop]$ grep -n '\.$' sw //以.結尾的,注意!!這里因為.有特殊含義,所以用轉義字符\
5:f8fj8.
7:huhuhuhuhu1huhu.
(4)任意一個字符. 與 重復字符* ,
如:[yuanyuan@localhost Desktop]$ grep -n 'h.h' sw //一個.代表一個字符
6:huhu7huhu
7:huhuhuhuhu1huhu.
*代表重復0個或多個前面的re字符,如g*g,g*代表空字符或一個以上的g
(5)連續n個{ },注意用轉義字符 \
[yuanyuan@localhost Desktop]$ grep -n 'w\{2\}' sw
4:fww1


2.sed (和akw一樣,都是行編輯器,逐行對數據進行處理)
sed 是一種在線編輯器(,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接着用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。接着處理下一行,這樣不斷重復,直到文件末尾。文件內容並沒有 改變,除非你使用重定向存儲輸出。
它的強大之處在於可以以行的方式來腳本化處理文本.它的主要功能就是刪,查,換和添加.
命令格式:
(1)sed [options] 'command' file(s)  
(2)sed [options] -f scrīptfile file(s) 
options:
-e command, --expression=command 允許多台編輯。
-h, --help 打印幫助,並顯示bug列表的地址。
-n, --quiet, --silent 取消默認輸出。
-f, --filer=scrīpt-file 引導sed腳本文件名。
-V, --version 打印版本和版權信息。

command:(常用的)
a/ 在當前行后面加入一行文本。
b lable 分支到腳本中帶有標記的地方,如果分支不存在則分支到腳本的末尾。 
c/ 用新的文本改變本行的文本。 
d 從模板塊(Pattern space)位置刪除行。 
D 刪除模板塊的第一行。 
i/ 在當前行上面插入文本。 
h 拷貝模板塊的內容到內存中的緩沖區。 
H 追加模板塊的內容到內存中的緩沖區。
g 獲得內存緩沖區的內容,並替代當前模板塊中的文本。 
G 獲得內存緩沖區的內容,並追加到當前模板塊文本的后面。
  
元字符集 
^ 錨定行的開始 如:/^sed/匹配所有以sed開頭的行。 
$ 錨定行的結束 如:/sed$/匹配所有以sed結尾的行。 
. 匹配一個非換行符的字符 如:/s.d/匹配s后接一個任意字符,然后是d。
* 匹配零或多個字符 如:/*sed/匹配所有模板是一個或多個空格后緊跟sed的行。 
[] 匹配一個指定范圍內的字符,如/[Ss]ed/匹配sed和Sed。 
[^] 匹配一個不在指定范圍內的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一個字母開頭,緊跟ed的行。 
/(../) 保存匹配的字符,如s//(love/)able//1rs,loveable被替換成lovers。 
& 保存搜索字符用來替換其他字符,如s/love/**&**/,love這成**love**。 
/< 錨定單詞的開始,如://<love/匹配包含以love開頭的單詞的行。 
/> 錨定單詞的結束,如/love/>/匹配包含以love結尾的單詞的行。 x/{m/} 重復字符x,m次,如:/0/{5/}/匹配包含5個o的行。 
x/{m,/} 重復字符x,至少m次,如:/o/{5,/}/匹配至少有5個o的行。 x/{m,n/} 重復字符x,至少m次,不多於n次,如:/o/{5,10/}/匹配5--10個o的行。 

實例 
2.1刪除:d命令
       *    $ sed '2d' example-----刪除example文件的第二行。
       *    $ sed '2,$d' example-----刪除example文件的第二行到末尾所有行。
       *    $ sed '$d' example-----刪除example文件的最后一行。
       *    $ sed '/test/'d example-----刪除example文件所有包含test的行。
2.2替換:s命令
       *    $ sed 's/test/mytest/g' example-----在整行范圍內把test替換為mytest。如果沒有g標記,則只有每行第一個匹配的test被替換成mytest。
       *    $ sed -n 's/^test/mytest/p' example-----(-n)選項和p標志一起使用表示只打印那些發生替換的行。也就是說,如果某一行開頭的test被替換成mytest,就打印它。
       *    $ sed 's/^192.168.0.1/&localhost/' example-----&符號表示替換換字符串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成它自已加 localhost,變成192.168.0.1localhost。
       *    $ sed -n 's//(love/)able//1rs/p' example-----love被標記為1,所有loveable會被替換成lovers,而且替換的行會被打印出來。
       *    $ sed 's#10#100#g' example-----不論什么字符,緊跟着s命令的都被認為是新的分隔符,所以,“#”在這里是分隔符,代替了默認的“/”分隔符。表示把所有10替換成100。
2.3選定行的范圍:逗號
       *    $ sed -n '/test/,/check/p' example-----所有在模板test和check所確定的范圍內的行都被打印。
       *    $ sed -n '5,/^test/p' example-----打印從第五行開始到第一個包含以test開始的行之間的所有行。
       *    $ sed '/test/,/check/s/$/sed test/' example-----對於模板test和west之間的行,每行的末尾用字符串sed test替換。
2.4多點編輯:e命令 
       *    $ sed -e '1,5d' -e 's/test/check/' example-----(-e)選項允許在同一行里執行多條命令。如例子所示,第一條命令刪除1至5行,第二條命令用check替換test。命令的執 行順序對結果有影響。如果兩個命令都是替換命令,那么第一個替換命令將影響第二個替換命令的結果。
       *    $ sed --expression='s/test/check/' --expression='/love/d' example-----一個比-e更好的命令是--expression。它能給sed表達式賦值。
2.5從文件讀入:r命令 
       *    $ sed '/test/r file' example-----file里的內容被讀進來,顯示在與test匹配的行后面,如果匹配多行,則file的內容將顯示在所有匹配行的下面。
2.6寫入文件:w命令
       *    $ sed -n '/test/w file' example-----在example中所有包含test的行都被寫入file里。
2.7追加命令:a命令
       *    $ sed '/^test/a//--->this is a example' example<-----'this is a example'被追加到以test開頭的行后面,sed要求命令a后面有一個反斜杠。
2.8插入:i命令
   $ sed '/test/i//
   new line
   -------------------------' example
   如果test被匹配,則把反斜杠后面的文本插入到匹配行的前面。
下一個:n命令
       *    $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,則移動到匹配行的下一行,替換這一行的aa,變為bb,並打印該行,然后繼續。
2.9變形:y命令 
       *    $ sed '1,10y/abcde/ABCDE/' example-----把1--10行內所有abcde轉變為大寫,注意,正則表達式元字符不能使用這個命令。
2.10退出:q命令 
       *    $ sed '10q' example-----打印完第10行后,退出sed。
2.11保持和獲取:h命令和G命令 
       *    $ sed -e '/test/h' -e '$G example-----在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩沖區中,除非行被刪除或者輸出被取消,否則所有被處理的行都將 打印在屏幕上。接着模式空間被清空,並存入新的一行等待處理。在這個例子里,匹配test的行被找到后,將存入模式空間,h命令將其復制並存入一個稱為保 持緩存區的特殊緩沖區內。第二條語句的意思是,當到達最后一行后,G命令取出保持緩沖區的行,然后把它放回模式空間中,且追加到現在已經存在於模式空間中 的行的末尾。在這個例子中就是追加到最后一行。簡單來說,任何包含test的行都被復制並追加到該文件的末尾。
2.12保持和互換:h命令和x命令 
       *    $ sed -e '/test/h' -e '/check/x' example -----互換模式空間和保持緩沖區的內容。也就是把包含test與check的行互換。
腳本 
Sed腳本是一個sed的命令清單,啟動Sed時以-f選項引導腳本文件名。Sed對於腳本中輸入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多個命令,要用分號分隔。以#開頭的行為注釋行,且不能跨行。
   *    在sed的命令行中引用shell變量時要使用雙引號,而不是通常所用的單引號。下面是一個根據name變量的內容來刪除named.conf文件中zone段的腳本:
     name='zone/ "localhost"'
     sed "/$name/,/};/d" named.conf

[yuanyuan@localhost Desktop]$ cat don.txt |sed -e '4d' -e '6c woxiangya' >haha //刪除第4行,將前6行復制到haha中,
sed有兩個以上的參數時需要用-e ,注意,源文件一直不變,變的是haha

 

3.awk(主要用於域的作用)
命令行方式
awk '{pattern + action}' {filenames}
awk [-F field-separator] 'commands' input-file(s)

其中,commands 是真正awk命令,[-F域分隔符]是可選的。 input-file(s) 是待處理的文件。
在awk中,文件的每一行中,由域分隔符分開的每一項稱為一個域。通常,在不指名-F域分隔符的情況下,默認的域分隔符是空格。

(1)[yuanyuan@localhost Desktop]$ last -n 5 |awk '{print $1}'
yuanyuan
yuanyuan
yuanyuan
reboot
yuanyuan
(2)[yuanyuan@localhost Desktop]$ last -n 5 |awk '{print $1 "\t" $3}' //第一域和第三域,中間以tab鍵隔開
yuanyuan :0.0
yuanyuan :0.0
yuanyuan :0
reboot boot
yuanyuan :0.0

wtmp Mon
(3)[yuanyuan@localhost Desktop]$ last -n 5 |awk '{print $1 "\t lines:" NR $3 "\t colums:" NF }' //NR顯示行號,NF顯示有多少個字符
yuanyuan lines:1:0.0 colums:10
yuanyuan lines:2:0.0 colums:10
yuanyuan lines:3:0 colums:10
reboot lines:4boot colums:11
yuanyuan lines:5:0.0 colums:10
lines:6 colums:0
wtmp lines:7Mon colums:7
(4)[yuanyuan@localhost Desktop]$ cat /etc/passwd | awk 'BEGIN{":"} $3>10 {print $1 "\t" $3 }' //用BEGIN來顯示變量的要求
第三列大於10的所有的第一列與第三列

更詳細的可以見:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

4.比較兩個文件

(1)diff: 以行為單位比較
diff -s file 1 file 2 結果顯示
[yuanyuan@localhost Desktop]$ diff -s don.txt haha
5,6c5 //5,6行被替換成右邊的
< yuan
< do
---
> woxiangya
(2)cmp: 以位為單位比較,主要用於二進制文件比較
cmp -s file 1 file 2
(3)patch (補丁文件,用diff比較后生成補丁文件)
diff 舊文件/新文件 > diff.patch

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM