Sed命令詳解linux
Table of Contents
1. Sed簡介
2. 定址
3. Sed命令
4. 選項
5. 元字符集
6. 實例
7. 腳本正則表達式
1. Sed簡介算法
sed是一種在線編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。文件內容並無 改變,除非你使用重定向存儲輸出。Sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操做;編寫轉換程序等。如下介紹的是Gnu版本的Sed 3.02。
2. 定址shell
能夠經過定址來定位你所但願編輯的行,該地址用數字構成,用逗號分隔的兩個行數表示以這兩行爲起止的行的範圍(包括行數表示的那兩行)。如1,3表示1,2,3行,美圓符號($)表示最後一行。範圍能夠經過數據,正則表達式或者兩者結合的方式肯定 。express
3. Sed命令apache
調用sed命令有兩種形式:跨域
sed [options] 'command' file(s)緩存
sed [options] -f scriptfile file(s)安全
<
a/
在當前行後面加入一行文本。bash
b lable
分支到腳本中帶有標記的地方,若是分支不存在則分支到腳本的末尾。
c/
用新的文本改變本行的文本。
d
從模板塊(Pattern space)位置刪除行。
D
刪除模板塊的第一行。
i/
在當前行上面插入文本。
h
拷貝模板塊的內容到內存中的緩衝區。
H
追加模板塊的內容到內存中的緩衝區
g
得到內存緩衝區的內容,並替代當前模板塊中的文本。
G
得到內存緩衝區的內容,並追加到當前模板塊文本的後面。
l
列表不能打印字符的清單。
n
讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。
N
追加下一個輸入行到模板塊後面並在兩者間嵌入一個新行,改變當前行號碼。
p
打印模板塊的行。
P(大寫)
打印模板塊的第一行。
q
退出Sed。
r file
從file中讀行。
t label
if分支,從最後一行開始,條件一旦知足或者T,t命令,將致使分支到帶有標號的命令處,或者到腳本的末尾。
T label
錯誤分支,從最後一行開始,一旦發生錯誤或者T,t命令,將致使分支到帶有標號的命令處,或者到腳本的末尾。
w file
寫並追加模板塊到file末尾。
W file
寫並追加模板塊的第一行到file末尾。
!
表示後面的命令對全部沒有被選定的行發生做用。
s/re/string
用string替換正則表達式re。
=
打印當前行號碼。
#
把註釋擴展到下一個換行符之前。
如下的是替換標記
g表示行內全面替換。
p表示打印行。
w表示把行寫入一個文件。
x表示互換模板塊中的文本和緩衝區中的文本。
y表示把一個字符翻譯爲另外的字符(可是不用於正則表達式)
4. 選項
<
-e command, --expression=command
容許多臺編輯。
-h, --help
打印幫助,並顯示bug列表的地址。
-n, --quiet, --silent
取消默認輸出。
-f, --filer=script-file
引導sed腳本文件名。
-V, --version
打印版本和版權信息。
5. 元字符集
<
^
錨定行的開始 如:/^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結尾的單詞的行。
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的行。
6. 實例
刪除:d命令
$ sed '2d' example-----刪除example文件的第二行。
$ sed '2,$d' example-----刪除example文件的第二行到末尾全部行。
$ sed '$d' example-----刪除example文件的最後一行。
$ sed '/test/'d example-----刪除example文件全部包含test的行。
替換: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。
選定行的範圍:逗號
$ 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替換。
多點編輯: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表達式賦值。
從文件讀入:r命令
$ sed '/test/r file' example-----file裏的內容被讀進來,顯示在與test匹配的行後面,若是匹配多行,則file的內容將顯示在全部匹配行的下面。
寫入文件:w命令
$ sed -n '/test/w file' example-----在example中全部包含test的行都被寫入file裏。
追加命令:a命令
$ sed '/^test/a//--->this is a example' example<-----'this is a example'被追加到以test開頭的行後面,sed要求命令a後面有一個反斜槓。
插入:i命令
$ sed '/test/i//
new line
-------------------------' example
若是test被匹配,則把反斜槓後面的文本插入到匹配行的前面。
下一個:n命令
$ sed '/test/{ n; s/aa/bb/; }' example-----若是test被匹配,則移動到匹配行的下一行,替換這一行的aa,變爲bb,並打印該行,而後繼續。
變形:y命令
$ sed '1,10y/abcde/ABCDE/' example-----把1--10行內全部abcde轉變爲大寫,注意,正則表達式元字符不能使用這個命令。
退出:q命令
$ sed '10q' example-----打印完第10行後,退出sed。
保持和獲取:h命令和G命令
$ sed -e '/test/h' -e '$G example-----在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩衝區中,除非行被刪除或者輸出被取消,不然全部被處理的行都將 打印在屏幕上。接着模式空間被清空,並存入新的一行等待處理。在這個例子裏,匹配test的行被找到後,將存入模式空間,h命令將其複製並存入一個稱爲保 持緩存區的特殊緩衝區內。第二條語句的意思是,當到達最後一行後,G命令取出保持緩衝區的行,而後把它放回模式空間中,且追加到如今已經存在於模式空間中 的行的末尾。在這個例子中就是追加到最後一行。簡單來講,任何包含test的行都被複制並追加到該文件的末尾。
保持和互換:h命令和x命令
$ sed -e '/test/h' -e '/check/x' example -----互換模式空間和保持緩衝區的內容。也就是把包含test與check的行互換。
7. 腳本
Sed腳本是一個sed的命令清單,啓動Sed時以-f選項引導腳本文件名。Sed對於腳本中輸入的命令很是挑剔,在命令的末尾不能有任何空白或文本,若是在一行中有多個命令,要用分號分隔。以#開頭的行爲註釋行,且不能跨行。
好比,若是要打印出含有字串」1024」的行,我就可能會用:
cat filename | sed –n ‘/1024/p’sed命令詳解!!(要學習shell的 朋友要好好看看)
sed /^$/d filename
能夠刪除文件中的空行。
sed /^[[:space:]]*$/d filename
能夠刪除內容爲多個空格/tab組成的行。
diff命令詳解
總覽
描述
在最簡單的狀況是, diff 比較兩個文件的內容 (源文件 和 目標文件). 文件名能夠是 - 由標準輸入設備讀入的文本. 做爲特別的狀況是, diff - - 比較一份標準輸入的它本身的拷貝若是 源文件 是一個目錄和 目標文件 不是(目錄), diff 會比較在 源文件(目錄) 裏的文件的中和 目標文件同名的(文件), 反過來也同樣. 非目錄文件不能是 -. 若是 源文件 和 目標文件 都是目錄, diff 比較兩個目錄中相應的文件,依照字母次序排序;這個比較是不會遞歸的,除非給出 -r 或者 --recursive. diff 不把一個目錄的內容看爲它是一個文件來比較。被指定的文件不能是標準的輸入, 由於標準的輸入是無名的而且"有同樣的名字的文件"的觀點不適用。 diff 的選項由 -, 開始因此正常地 源文件(名) 和 目標文件(名) 不能夠用 - 開頭. 然而, -- 能夠被它視爲保留的即便做爲文件名的開頭( they begin with -.)
選項
下面是 GNU所接受的 diff 的全部選項的概要. 大多數的選項有兩個相同的名字,一個是單個的跟在 - 後面字母, 另外一個是由 -- 引出的長名字. 多個單字母選項(除非它們產生歧義)可以組合爲單行的命令行語法 -ac是等同於 -a -c. 長命名的選項能被縮短到他們的名字的任何惟一的前綴. 用 ([ 和 ]) 括起來顯示選項產生歧義的選項
-行數(一個整數)
顯示上下文 行數 (一個整數). 這個選項自身沒有指定輸出格式,這是沒有效果的,除非和 -c 或者 -u 組合使用. 這是已廢置的選項,對於正確的操做, 上下文至少要有兩行。
-a
全部的文件都視爲文本文件來逐行比較,甚至他們彷佛不是文本文件.
-b
忽略空格引發的變化.
-B
忽略插入刪除空行引發的變化.
--brief
僅報告文件是否相異,在意差異的細節.
-c
使用上下文輸出格式.
-C 行數(一個整數)
--context[=lines]
使用上下文輸出格式,顯示以指定 行數 (一個整數), 或者是三行(當 行數 沒有給出時. 對於正確的操做, 上下文至少要有兩行.
--changed-group-format=format
使用 format 輸出一組包含兩個文件的不一樣處的行,其格式是 if-then-else .
-d
改變算法也許發現變化的一個更小的集合.這會使 diff 變慢 (有時更慢).
-D name
合併 if-then-else 格式輸出, 預處理宏(由name參數提供)條件.
-e
--ed
輸出爲一個有效的 ed 腳本.
--exclude=pattern
比較目錄的時候,忽略和目錄中與 pattern(樣式) 相配的.
--exclude-from=file
比較目錄的時候,忽略和目錄中與任何包含在 file(文件) 的樣式相配的文件和目錄.
--expand-tabs
在輸出時擴展tab爲空格,保護輸入文件的tab對齊方式
-f
產生一個很象 ed 腳本的輸出,可是可是在他們在文件出現的順序有改變
-F regexp
在上下文和統一格式中,對於每一大塊的不一樣,顯示出匹配 regexp. 的一些前面的行.
--forward-ed
產生象 ed 腳本的輸出,可是它們在文件出現的順序有改變。
-h
這選項如今已沒做用,它呈現Unix的兼容性.
-H
使用啓發規則加速操做那些有許多離散的小差別的大文件.
--horizon-lines=lines
比較給定行數的有共同前綴的最後行,和有共同或綴的最前行.
-i
忽略大小寫.
-I regexp
忽略由插入,刪除行(由regexp 參數提供參考)帶來的改變.
--ifdef=name
合併 if-then-else 格式輸出, 預處理宏(由name參數提供)條件.
--ignore-all-space
在比較行的時候忽略空白.
--ignore-blank-lines
忽略插入和刪除空行
--ignore-case
忽略大小寫.
--ignore-matching-lines=regexp
忽略插入刪除行(由regexp 參數提供參考).
--ignore-space-change
忽略空白的數量.
--initial-tab
在文本行(不管是常規的或者格式化的先後文關係)前輸出tab代替空格. 引發的緣由是tab對齊方式看上去象是常規的同樣.
-l
產生經過 pr 編碼的輸出.
-L label
--label=label
使用 label 給出的字符在文件頭代替文件名輸出.
--left-column
以並列方式印出兩公共行的左邊
--line-format=format
使用 format 輸出全部的行,在 if-then-else 格式中.
--minimal
改變算法也許發現變化的一個更小的集合.這會使 diff 變慢 (有時更慢).
-n
輸出 RC-格式 diffs; 除了每條指令指定的行數受影響外 象 -f 同樣。
-N
--new-file
在目錄比較中,若是那個文件只在其中的一個目錄中找到,那麼它被視爲在另外一個目錄中是一個空文件.
--new-group-format=format
使用 format 以if-then-else 格式輸出只在第二個文件中取出的一個行組
--new-line-format=format
使用 format 以if-then-else 格式輸出只在第二個文件中取出的一行
--old-group-format=format
使用 format 以if-then-else 格式輸出只在第一個文件中取出的一個行組
--old-line-format=format
使用 format 使用 format 以if-then-else 格式輸出只在第一個文件中取出的一行
-p
顯示帶有c函數的改變.
-P
在目錄比較中,若是那個文件只在其中的一個目錄中找到,那麼它被視爲在另外一個目錄中是一個空文件.
--paginate
產生經過 pr 編碼的輸出.
-q
僅報告文件是否相異,不報告詳細的差別.
-r
當比較目錄時,遞歸比較任何找到的子目錄.
--rcs
輸出 RC-格式 diffs; 除了每條指令指定的行數受影響外 象 -f 同樣。
--recursive
當比較目錄時,遞歸比較任何找到的子目錄.
--report-identical-files
-s
報告兩個文件相同.
-S file
當比較目錄時,由 file 開始. 這用於繼續中斷了的比較.
--sdiff-merge-assist
打印附加的信息去幫助 sdiff. sdiff 在運行 diff 時使用這些選項. 這些選項不是特地爲使用者直接使用而準備的。
--show-c-function
顯示帶有c函數的改變.
--show-function-line=regexp
在上下文和統一的格式,對於每一大塊的差異,顯示出匹配 regexp. 的一些前面的行
--side-by-side
使用並列的輸出格式.
--speed-large-files
使用啓發規則加速操做那些有許多離散的小差別的大文件.
--starting-file=file
當比較目錄時,由 file 開始. 這用於繼續中斷了的比較.
--suppress-common-lines
在並列格式中不印出公共行。
-t
在輸出時擴展tab爲空格,保護輸入文件的tab對齊方式
-T
在文本行(不管是常規的或者格式化的先後文關係)前輸出tab代替空格.引發的緣由是tab對齊方式看上去象是常規的同樣.
--text
全部的文件都視爲文本文件來逐行比較,甚至他們彷佛不是文本文件.
-u
使用統一的輸出格式.
--unchanged-group-format=format
使用 format 輸出兩個文件的公共行組,其格式是if-then-else.
--unchanged-line-format=format
使用 format 輸出兩個文件的公共行,其格式是if-then-else.
--unidirectional-new-file
在目錄比較中,若是那個文件只在其中的一個目錄中找到,那麼它被視爲在另外一個目錄中是一個空文件.
-U lines
--unified[=lines]
使用先後關係格式輸出,顯示以指定 行數 (一個整數), 或者是三行(當 行數 沒有給出時. 對於正確的操做, 上下文至少要有兩行.
-v
--version
輸出 diff 版本號.
-w
在比較行時忽略空格
-W columns
--width=columns
在並列格式輸出時,使用指定的列寬.
-x pattern
比較目錄的時候,忽略和目錄中與 pattern(樣式) 相配的.
-X file
比較目錄的時候,忽略和目錄中與任何包含在 file(文件) 的樣式相配的文件和目錄.
-y
使用並列格式輸出
實例:有這樣兩個文件:程序清單1 :hello.c#include
int main(void)
{
char msg[] = "Hello world!";
puts(msg);
printf("Welcome to use diff commond.\n");
return 0;
}程序清單2:hello_diff.c#include
#include
int main(void)
{
char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}咱們使用diff命令來查看這兩個文件的不一樣之處,有一下幾種方便的方法:
1、普通格式輸出:[root@localhost diff]# diff hello.c hello_diff.c
1a2
> #include
5c6
char msg[] = "Hello world,fome hello_diff.c";
8c9
printf("hello_diff.c says,'Here you are,using diff.'\n");
[root@localhost diff]# 上面的「1a2」表示後面的一個文件"hello_diff.c"比前面的一個文件"hello.c"多了一行
"5c6"表示第一個文件的第5行與第二個文件的第6行有區別
2、並排格式輸出[root@localhost diff]# diff hello.c hello_diff.c -y -W 130
#include #include
> #include
int main(void) int main(void)
{ {
char msg[] = "Hello world!"; | char msg[] = "Hello world,fome hello_diff.c";
puts(msg); puts(msg);
printf("Welcome to use diff commond.\n"); | printf("hello_diff.c says,'Here you are,using diff.'\
return 0; return 0;
} }
[root@localhost diff]# 這種並排格式的對比一目瞭然,能夠快速找到不一樣的地方。
-W選擇能夠指定輸出列的寬度,這裏指定輸出列寬爲130
3、上下文輸出格式[root@localhost diff]# diff hello.c hello_diff.c -c
*** hello.c 2007-09-25 17:54:51.000000000 +0800
--- hello_diff.c 2007-09-25 17:56:00.000000000 +0800
***************
*** 1,11 ****
#include
int main(void)
{
! char msg[] = "Hello world!";
puts(msg);
! printf("Welcome to use diff commond.\n");
return 0;
}
--- 1,12 ----
#include
+ #include
int main(void)
{
! char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
! printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 這種方式在開頭兩行做了比較文件的說明,這裏有三中特殊字符:+ 比較的文件的後者比前着多一行- 比較的文件的後者比前着少一行 ! 比較的文件二者有差異的行
4、統一輸出格式[root@localhost diff]# diff hello.c hello_diff.c -u
--- hello.c 2007-09-25 17:54:51.000000000 +0800
+++ hello_diff.c 2007-09-25 17:56:00.000000000 +0800
@@ -1,11 +1,12 @@
#include
+#include
int main(void)
{
- char msg[] = "Hello world!";
+ char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
- printf("Welcome to use diff commond.\n");
+ printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 正如看到的那樣,統一格式的輸出更加緊湊,因此更易於理解,更易於修改。
5、其餘假如你想查看兩個文件是否不一樣又不想顯示差別之處的話,能夠加上-q選項:[root@localhost diff]# diff hello.c hello_diff.c -q
Files hello.c and hello_diff.c differ
[root@localhost diff]# 另外你還能夠提供一些匹配規則來忽略某中差異,能夠用 -I regexp[root@localhost diff]# diff hello.c hello_diff.c -c -I include
*** hello.c 2007-09-25 17:54:51.000000000 +0800
--- hello_diff.c 2007-09-25 17:56:00.000000000 +0800
***************
*** 2,11 ****
int main(void)
{
! char msg[] = "Hello world!";
puts(msg);
! printf("Welcome to use diff commond.\n");
return 0;
}
--- 3,12 ----
int main(void)
{
! char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
! printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 這裏經過「 -I include」選項來忽略帶有「 include」字樣的行
Sort命令詳解
sort是在Linux裏很是經常使用的一個命令,管排序的,集中精力,五分鐘搞定sort,如今開始!
1 sort的工做原理
sort將文件的每一行做爲一個單位,相互比較,比較原則是從首字符向後,依次按ASCII碼值進行比較,最後將他們按升序輸出。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
2 sort的-u選項
它的做用很簡單,就是在輸出行中去除重複行。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear
pear因爲重複被-u選項無情的刪除了。
3 sort的-r選項
sort默認的排序方式是升序,若是想改爲降序,就加個-r就搞定了。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1
4 sort的-o選項
因爲sort默認是把結果輸出到標準輸出,因此須要用重定向才能將結果寫入文件,形如sort filename > newfile。
可是,若是你想把排序結果輸出到原文件中,用重定向可就不行了。
[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,居然將number清空了。
就在這個時候,-o選項出現了,它成功的解決了這個問題,讓你放心的將結果寫入原文件。這或許也是-o比重定向的惟一優點所在。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1
5 sort的-n選項
你有沒有遇到過10比2小的狀況。我反正遇到過。出現這種狀況是因爲排序程序將這些數字按字符來排序了,排序程序會先比較1和2,顯然1小,因此就將10放在2前面嘍。這也是sort的一向做風。
咱們若是想改變這種現狀,就要使用-n選項,來告訴sort,「要以數值來排序」!
[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19
6 sort的-t選項和-k選項
若是有一個文件的內容是這樣:
[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
這個文件有三列,列與列之間用冒號隔開了,第一列表示水果類型,第二列表示水果數量,第三列表示水果價格。
那麼我想以水果數量來排序,也就是以第二列來排序,如何利用sort實現?
幸虧,sort提供了-t選項,後面能夠設定間隔符。(是否是想起了cut和paste的-d選項,共鳴~~)
指定了間隔符以後,就能夠用-k來指定列數了。
[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
咱們使用冒號做爲間隔符,並針對第二列來進行數值升序排序,結果很使人滿意。
7 其餘的sort經常使用選項
-f會將小寫字母都轉換爲大寫字母來進行比較,亦即忽略大小寫
-c會檢查文件是否已排好序,若是亂序,則輸出第一個亂序的行的相關信息,最後返回1
-C會檢查文件是否已排好序,若是亂序,不輸出內容,僅返回1
-M會以月份來排序,好比JAN小於FEB等等
-b會忽略每一行前面的全部空白部分,從第一個可見字符開始比較。
有時候學習腳本,你會發現sort命令後面跟了一堆相似-k1,2,或者-k1.2 -k3.4的東東,有些匪夷所思。今天,咱們就來搞定它—-k選項!
1 準備素材
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
第一個域是公司名稱,第二個域是公司人數,第三個域是員工平均工資。(除了公司名稱,其餘的別信,都瞎寫的^_^)
2 我想讓這個文件按公司的字母順序排序,也就是按第一個域進行排序:(這個facebook.txt文件有三個域)
$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
看到了吧,就直接用-k 1設定就能夠了。(其實此處並不嚴格,稍後你就會知道)
3 我想讓facebook.txt按照公司人數排序
$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
不用解釋,我相信你能懂。
可是,此處出現了問題,那就是baidu和sohu的公司人數相同,都是100人,這個時候怎麼辦呢?按照默認規矩,是從第一個域開始進行升序排序,所以baidu排在了sohu前面。
4 我想讓facebook.txt按照公司人數排序 ,人數相同的按照員工平均工資升序排序:
$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
看,咱們加了一個-k2 -k3就解決了問題。對滴,sort支持這種設定,就是說設定域排序的優先級,先以第2個域進行排序,若是相同,再以第3個域進行排序。(若是你願意,能夠一直這麼寫下去,設定不少個排序優先級)
5 我想讓facebook.txt按照員工工資降序排序,若是員工人數相同的,則按照公司人數升序排序:(這個有點難度嘍)
$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
此處有使用了一些小技巧,你仔細看看,在-k 3後面偷偷加上了一個小寫字母r。你想一想,再結合咱們上一篇文章,能獲得答案麼?揭曉:r和-r選項的做用是同樣的,就是表示逆序。由於sort默認是按照升序排序的,因此此處須要加上r表示第三個域(員工平均工資)是按照降序排序。此處你還能夠加上n,就表示對這個域進行排序時,要按照數值大小進行排序,舉個例子吧:
$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
看,咱們去掉了最前面的-n選項,而是將它加入到了每個-k選項中了。
6 -k選項的具體語法格式
要繼續往下深刻的話,就不得不來點理論知識。你須要瞭解-k選項的語法格式,以下:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
這個語法格式能夠被其中的逗號(「,」)分爲兩大部分,Start部分和End部分。
先給你灌輸一個思想,那就是「若是不設定End部分,那麼就認爲End被設定爲行尾」。這個概念很重要的,但每每你不會重視它。
Start部分也由三部分組成,其中的Modifier部分就是咱們以前說過的相似n和r的選項部分。咱們重點說說Start部分的FStart和C.Start。
C.Start也是能夠省略的,省略的話就表示從本域的開頭部分開始。以前例子中的-k 2和-k 3就是省略了C.Start的例子嘍。
FStart.CStart,其中FStart就是表示使用的域,而CStart則表示在FStart域中從第幾個字符開始算「排序首字符」。
同理,在End部分中,你能夠設定FEnd.CEnd,若是你省略.CEnd,則表示結尾到「域尾」,即本域的最後一個字符。或者,若是你將CEnd設定爲0(零),也是表示結尾到「域尾」。
7 突發奇想,從公司英文名稱的第二個字母開始進行排序:
$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
看,咱們使用了-k 1.2,這就表示對第一個域的第二個字符開始到本域的最後一個字符爲止的字符串進行排序。你會發現baidu由於第二個字母是a而名列榜首。sohu和 google第二個字符都是o,但sohu的h在google的o前面,因此二者分別排在第二和第三。guge只能屈居第四了。
8 又突發奇想,,只針對公司英文名稱的第二個字母進行排序,若是相同的按照員工工資進行降序排序:
$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
因爲只對第二個字母進行排序,因此咱們使用了-k 1.2,1.2的表示方式,表示咱們「只」對第二個字母進行排序。(若是你問「我使用-k 1.2怎麼不行?」,固然不行,由於你省略了End部分,這就意味着你將對從第二個字母起到本域最後一個字符爲止的字符串進行排序)。對於員工工資進行排 序,咱們也使用了-k 3,3,這是最準確的表述,表示咱們「只」對本域進行排序,由於若是你省略了後面的3,就變成了咱們「對第3個域開始到最後一個域位置的內容進行排序」 了。
9 在modifier部分還能夠用到哪些選項?
能夠用到b、d、f、i、n 或 r。
其中n和r你確定已經很熟悉了。
b表示忽略本域的簽到空白符號。
d表示對本域按照字典順序排序(即,只考慮空白和字母)。
f表示對本域忽略大小寫進行排序。
i表示忽略「不可打印字符」,只針對可打印字符進行排序。(有些ASCII就是不可打印字符,好比\a是報警,\b是退格,\n是換行,\r是回車等等)
10 思考思考關於-k和-u聯合使用的例子:
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
這是最原始的facebook.txt文件。
$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000
當設定以公司員工域進行數值排序,而後加-u後,sohu一行就被刪除了!原來-u只識別用-k設定的域,發現相同,就將後續相同的行都刪除。
$ sort -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
$ sort -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
這個例子也同理,開頭字符是g的guge就沒有幸免於難。
$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
咦!這裏設置了兩層排序優先級的狀況下,使用-u就沒有刪除任何行。原來-u是會權衡全部-k選項,將都相同的纔會刪除,只要其中有一級不一樣都不會輕易刪除的:)(不信,你能夠本身加一行sina 100 4500試試看)
11 最詭異的排序:
$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
以第二個域的第二個字符開始到第三個域的第一個字符結束的部分進行排序。
第一行,會提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。
又由於sort認爲0小於00小於000小於0000….
所以0 3確定是在第一個。10 5確定是在最後一個。但爲何00 5卻在00 4前面呢?(你能夠本身作實驗思考一下。)
答案揭曉:原來「跨域的設定是個假象」,sort只會比較第二個域的第二個字符到第二個域的最後一個字符的部分,而不會把第三個域的開頭字符歸入比較範圍。當發現00和00相同時,sort就會自動比較第一個域去了。固然baidu在sohu前面了。用一個範例便可證明:
$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
shell中wc命令詳解
shell中wc命令詳解
wc命令的功能爲統計指定文件中的字節數、字數、行數, 並將統計結果顯示輸出。
語法:wc [選項] 文件…
說明:該命令統計給定文件中的字節數、字數、行數。若是沒有給出文件名,則從標準輸入讀取。wc同時也給出全部指定文件的總統計數。字是由空格字符區分開的最大字符串。
該命令各選項含義以下:
- c 統計字節數。
- l 統計行數。
- w 統計字數。
這些選項能夠組合使用。
輸出列的順序和數目不受選項的順序和數目的影響。老是按下述順序顯示而且每項最多一列。
行數、字數、字節數、文件名
若是命令行中沒有文件名,則輸出中不出現文件名。
例如:
$ wc - lcw file1 file2
4 33 file1
7 52 file2
11 11 85 total
省略任選項-lcw,wc命令的執行結果與上面同樣。
Find命令詳解
1、find命令的通常形式爲;
find pathname -options [-print -exec -ok ...]
2、find命令的參數;
· pathname: find命令所查找的目錄路徑。例如用.來表示當前目錄,用/來表示系統根目錄。
· -print: find命令將匹配的文件輸出到標準輸出。
· -exec: find命令對匹配的文件執行該參數所給出的shell命令。相應命令的形式爲"command { } \; ",注意"{ }"和「\;」之間的空格。
· -ok: 和-exec的做用相同,只不過以一種更爲安全的模式來執行該參數所給出的shell命令,在執行每個命令以前,都會給出提示,讓用戶來肯定是否執行。
3、find命令選項
-name 按照文件名查找文件。
-perm 按照文件權限來查找文件。
-prune 使用這一選項可使find命令不在當前指定的目錄中查找,若是同時使用-depth選項,那麼-prune將被find命令忽略。
-user 按照文件屬主來查找文件。
-group 按照文件所屬的組來查找文件。
-mtime -n +n 按照文件的更改時間來查找文件, - n表示文件更改時間距如今n天之內,+ n表示文件更改時間距如今n天之前。find命令還有-atime和-ctime 選項,但它們都和-m time選項。
-nogroup 查找無有效所屬組的文件,即該文件所屬的組在/etc/groups中不存在。
-nouser 查找無有效屬主的文件,即該文件的屬主在/etc/passwd中不存在。
-newer file1 ! file2 查找更改時間比文件file1新但比文件file2舊的文件。
-type 查找某一類型的文件,諸如:b - 塊設備文件。d - 目錄。c - 字符設備文件。p - 管道文件。l - 符號連接文件。f - 普通文件。
-size n:[c] 查找文件長度爲n塊的文件,帶有c時表示文件長度以字節計。
-depth:在查找文件時,首先查找當前目錄中的文件,而後再在其子目錄中查找。
-fstype:查找位於某一類型文件系統中的文件,這些文件系統類型一般能夠在配置文件/etc/fstab中找到,該配置文件中包含了本系統中有關文件系統的信息。
-mount:在查找文件時不跨越文件系統mount點。
-follow:若是find命令遇到符號連接文件,就跟蹤至連接所指向的文件。
-cpio:對匹配的文件使用cpio命令,將這些文件備份到磁帶設備中。
另外,下面三個的區別:
-amin n 查找系統中最後N分鐘訪問的文件
-atime n 查找系統中最後n*24小時訪問的文件
-cmin n 查找系統中最後N分鐘被改變文件狀態的文件
-ctime n 查找系統中最後n*24小時被改變文件狀態的文件
-mmin n 查找系統中最後N分鐘被改變文件數據的文件
-mtime n 查找系統中最後n*24小時被改變文件數據的文件
4、使用exec或ok來執行shell命令
使用find時,只要把想要的操做寫在一個文件裏,就能夠用exec來配合find查找,很方便的
在有些操做系統中只容許-exec選項執行諸如l s或ls -l這樣的命令。大多數用戶使用這一選項是爲了查找舊文件並刪除它們。建議在真正執行rm命令刪除文件以前,最好先用ls命令看一下,確認它們是所要刪除的文件。
exec選項後面跟隨着所要執行的命令或腳本,而後是一對兒{ },一個空格和一個\,最後是一個分號。爲了使用exec選項,必需要同時使用print選項。若是驗證一下find命令,會發現該命令只輸出從當前路徑起的相對路徑及文件名。
例如:爲了用ls -l命令列出所匹配到的文件,能夠把ls -l命令放在find命令的-exec選項中
# find . -type f -exec ls -l { } \;
-rw-r--r-- 1 root root 34928 2003-02-25 ./conf/httpd.conf
-rw-r--r-- 1 root root 12959 2003-02-25 ./conf/magic
-rw-r--r-- 1 root root 180 2003-02-25 ./conf.d/README
上面的例子中,find命令匹配到了當前目錄下的全部普通文件,並在-exec選項中使用ls -l命令將它們列出。
在/logs目錄中查找更改時間在5日之前的文件並刪除它們:
$ find logs -type f -mtime +5 -exec rm { } \;
記住:在shell中用任何方式刪除文件以前,應當先查看相應的文件,必定要當心!當使用諸如mv或rm命令時,可使用-exec選項的安全模式。它將在對每一個匹配到的文件進行操做以前提示你。
在下面的例子中, find命令在當前目錄中查找全部文件名以.LOG結尾、更改時間在5日以上的文件,並刪除它們,只不過在刪除以前先給出提示。
$ find . -name "*.conf" -mtime +5 -ok rm { } \;
< rm ... ./conf/httpd.conf > ? n
按y鍵刪除文件,按n鍵不刪除。
任何形式的命令均可以在-exec選項中使用。
在下面的例子中咱們使用grep命令。find命令首先匹配全部文件名爲「 passwd*」的文件,例如passwd、passwd.old、passwd.bak,而後執行grep命令看看在這些文件中是否存在一個sam用戶。
# find /etc -name "passwd*" -exec grep "sam" { } \;
sam:x:501:501::/usr/sam:/bin/bash
2、find命令的例子;
1、查找當前用戶主目錄下的全部文件:下面兩種方法均可以使用
$ find $HOME -print
$ find ~ -print
2、讓當前目錄中文件屬主具備讀、寫權限,而且文件所屬組的用戶和其餘用戶具備讀權限的文件;
$ find . -type f -perm 644 -exec ls -l { } \;
3、爲了查找系統中全部文件長度爲0的普通文件,並列出它們的完整路徑;
$ find / -type f -size 0 -exec ls -l { } \;
4、查找/var/logs目錄中更改時間在7日之前的普通文件,並在刪除以前詢問它們;
$ find /var/logs -type f -mtime +7 -ok rm { } \;
5、爲了查找系統中全部屬於root組的文件;
$find . -group root -exec ls -l { } \;
-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1
6、find命令將刪除當目錄中訪問時間在7日以來、含有數字後綴的admin.log文件。
該命令只檢查三位數字,因此相應文件的後綴不要超過999。先建幾個admin.log*的文件 ,才能使用下面這個命令
$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok
rm { } \;
< rm ... ./admin.log001 > ? n
< rm ... ./admin.log002 > ? n
< rm ... ./admin.log042 > ? n
< rm ... ./admin.log942 > ? n
7、爲了查找當前文件系統中的全部目錄並排序;
$ find . -type d | sort
8、爲了查找系統中全部的rmt磁帶設備;
$ find /dev/rmt -print
3、find 命令的參數
下面是find一些經常使用參數的例子,有用到的時候查查就好了,像上面前幾個貼子,都用到了其中的的一些參數,也能夠用man或查看論壇裏其它貼子有find的命令手冊
1、使用name選項
文件名選項是find命令最經常使用的選項,要麼單獨使用該選項,要麼和其餘選項一塊兒使用。
可使用某種文件名模式來匹配文件,記住要用引號將文件名模式引發來。
無論當前路徑是什麼,若是想要在本身的根目錄$HOME中查找文件名符合*.txt的文件,使用~做爲 'pathname'參數,波浪號~表明了你的$HOME目錄。
$ find ~ -name "*.txt" -print
想要在當前目錄及子目錄中查找全部的‘ *.txt’文件,能夠用:
$ find . -name "*.txt" -print
想要的當前目錄及子目錄中查找文件名以一個大寫字母開頭的文件,能夠用:
$ find . -name "[A-Z]*" -print
想要在/etc目錄中查找文件名以host開頭的文件,能夠用:
$ find /etc -name "host*" -print
想要查找$HOME目錄中的文件,能夠用:
$ find ~ -name "*" -print 或find . -print
要想讓系統高負荷運行,就從根目錄開始查找全部的文件。
$ find / -name "*" -print
若是想在當前目錄查找文件名以兩個小寫字母開頭,跟着是兩個數字,最後是.txt的文件,下面的命令就可以返回名爲ax37.txt的文件:
$find . -name "[a-z][a-z][0--9][0--9].txt" -print
2、用perm選項
按照文件權限模式用-perm選項,按文件權限模式來查找文件的話。最好使用八進制的權限表示法。
如在當前目錄下查找文件權限位爲755的文件,即文件屬主能夠讀、寫、執行,其餘用戶能夠讀、執行的文件,能夠用:
$ find . -perm 755 -print
還有一種表達方法:在八進制數字前面要加一個橫槓-,表示都匹配,如-007就至關於777,-006至關於666
# ls -l
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
# find . -perm 006
# find . -perm -006
./sam
./httpd1.conf
./temp
-perm mode:文件許可正好符合mode
-perm +mode:文件許可部分符合mode
-perm -mode: 文件許可徹底符合mode
3、忽略某個目錄
若是在查找文件時但願忽略某個目錄,由於你知道那個目錄中沒有你所要查找的文件,那麼可使用-prune選項來指出須要忽略的目錄。在使用-prune選項時要小心,由於若是你同時使用了-depth選項,那麼-prune選項就會被find命令忽略。
若是但願在/apps目錄下查找文件,但不但願在/apps/bin目錄下查找,能夠用:
$ find /apps -path "/apps/bin" -prune -o -print
4、使用find查找文件的時候怎麼避開某個文件目錄
好比要在/usr/sam目錄下查找不在dir1子目錄以內的全部文件
find /usr/sam -path "/usr/sam/dir1" -prune -o -print
find [-path ..] [expression] 在路徑列表的後面的是表達式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o
-print 的簡寫表達式按順序求值, -a 和 -o 都是短路求值,與 shell 的 && 和 || 相似若是 -path "/usr/sam" 爲真,則求值 -prune , -prune 返回真,與邏輯表達式爲真;不然不求值 -prune,與邏輯表達式爲假。若是 -path "/usr/sam" -a -prune 爲假,則求值 -print ,-print返回真,或邏輯表達式爲真;不然不求值 -print,或邏輯表達式爲真。
這個表達式組合特例能夠用僞碼寫爲
if -path "/usr/sam" then
-prune
else
避開多個文件夾
find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print
圓括號表示表達式的結合。
\ 表示引用,即指示 shell 不對後面的字符做特殊解釋,而留給 find 命令去解釋其意義。
查找某一肯定文件,-name等選項加在-o 以後
#find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print
5、使用user和nouser選項
按文件屬主查找文件,如在$HOME目錄中查找文件屬主爲sam的文件,能夠用:
$ find ~ -user sam -print
在/etc目錄下查找文件屬主爲uucp的文件:
$ find /etc -user uucp -print
爲了查找屬主賬戶已經被刪除的文件,可使用-nouser選項。這樣就可以找到那些屬主在/etc/passwd文件中沒有有效賬戶的文件。在使用-nouser選項時,沒必要給出用戶名; find命令可以爲你完成相應的工做。
例如,但願在/home目錄下查找全部的這類文件,能夠用:
$ find /home -nouser -print
6、使用group和nogroup選項
就像user和nouser選項同樣,針對文件所屬於的用戶組, find命令也具備一樣的選項,爲了在/apps目錄下查找屬於gem用戶組的文件,能夠用:
$ find /apps -group gem -print
要查找沒有有效所屬用戶組的全部文件,可使用nogroup選項。下面的find命令從文件系統的根目錄處查找這樣的文件
$ find / -nogroup-print
7、按照更改時間或訪問時間等查找文件
若是但願按照更改時間來查找文件,可使用mtime,atime或ctime選項。若是系統忽然沒有可用空間了,頗有可能某一個文件的長度在此期間增加迅速,這時就能夠用mtime選項來查找這樣的文件。
用減號-來限定更改時間在距今n日之內的文件,而用加號+來限定更改時間在距今n日之前的文件。
但願在系統根目錄下查找更改時間在5日之內的文件,能夠用:
$ find / -mtime -5 -print
爲了在/var/adm目錄下查找更改時間在3日之前的文件,能夠用:
$ find /var/adm -mtime +3 -print
8、查找比某個文件新或舊的文件
若是但願查找更改時間比某個文件新但比另外一個文件舊的全部文件,可使用-newer選項。它的通常形式爲:
newest_file_name ! oldest_file_name
其中,!是邏輯非符號。
查找更改時間比文件sam新但比文件temp舊的文件:
例:有兩個文件
-rw-r--r-- 1 sam adm 0 10月 31 01:07 fiel
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
# find -newer httpd1.conf ! -newer temp -ls
1077669 0 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 ./httpd.conf
1077671 4 -rw-rw-rw- 1 root root 2792 10月 31 20:19 ./temp
1077673 0 -rw-r--r-- 1 sam adm 0 10月 31 01:07 ./fiel
查找更改時間在比temp文件新的文件:
$ find . -newer temp -print
9、使用type選項
在/etc目錄下查找全部的目錄,能夠用:
$ find /etc -type d -print
在當前目錄下查找除目錄之外的全部類型的文件,能夠用:
$ find . ! -type d -print
在/etc目錄下查找全部的符號連接文件,能夠用
$ find /etc -type l -print
10、使用size選項
能夠按照文件長度來查找文件,這裏所指的文件長度既能夠用塊(block)來計量,也能夠用字節來計量。以字節計量文件長度的表達形式爲N c;以塊計量文件長度只用數字表示便可。
在按照文件長度查找文件時,通常使用這種以字節表示的文件長度,在查看文件系統的大小,由於這時使用塊來計量更容易轉換。
在當前目錄下查找文件長度大於1 M字節的文件:
$ find . -size +1000000c -print
在/home/apache目錄下查找文件長度剛好爲100字節的文件:
$ find /home/apache -size 100c -print
在當前目錄下查找長度超過10塊的文件(一塊等於512字節):
$ find . -size +10 -print
11、使用depth選項
在使用find命令時,可能但願先匹配全部的文件,再在子目錄中查找。使用depth選項就可使find命令這樣作。這樣作的一個緣由就是,當在使用find命令向磁帶上備份文件系統時,但願首先備份全部的文件,其次再備份子目錄中的文件。
在下面的例子中, find命令從文件系統的根目錄開始,查找一個名爲CON.FILE的文件。
它將首先匹配全部的文件而後再進入子目錄中查找。
$ find / -name "CON.FILE" -depth -print
cut是一個選取命令,就是將一段數據通過分析,取出咱們想要的。通常來講,選取信息一般是針對「行」來進行分析的,並非整篇信息分析的。
(1)其語法格式爲:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
使用說明
cut 命令從文件的每一行剪切字節、字符和字段並將這些字節、字符和字段寫至標準輸出。
若是不指定 File 參數,cut 命令將讀取標準輸入。必須指定 -b、-c 或 -f 標誌之一。
主要參數
-b :以字節爲單位進行分割。這些字節位置將忽略多字節字符邊界,除非也指定了 -n 標誌。
-c :以字符爲單位進行分割。
-d :自定義分隔符,默認爲製表符。
-f :與-d一塊兒使用,指定顯示哪一個區域。
-n :取消分割多字節字符。僅和 -b 標誌一塊兒使用。若是字符的最後一個字節落在由 -b 標誌的 List 參數指示的<br />範圍以內,該字符將被寫出;不然,該字符將被排除。
(2)cut通常以什麼爲依據呢? 也就是說,我怎麼告訴cut我想定位到的剪切內容呢?
cut命令主要是接受三個定位方法:
第一,字節(bytes),用選項-b
第二,字符(characters),用選項-c
第三,域(fields),用選項-f
(3)以「字節」定位
舉個例子吧,當你執行ps命令時,會輸出相似以下的內容:
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
若是咱們想提取每一行的第3個字節,就這樣:
[rocrocket@rocrocket programming]$ who|cut -b 3
c
c
c
(4) 若是「字節」定位中,我想提取第3,第4、第5和第8個字節,怎麼辦?
-b支持形如3-5的寫法,並且多個定位之間用逗號隔開就成了。看看例子吧:
[rocrocket@rocrocket programming]$ who|cut -b 3-5,8
croe
croe
croe
但有一點要注意,cut命令若是使用了-b選項,那麼執行此命令時,cut會先把-b後面全部的定位進行從小到大排序,而後再提取。可不能顛倒定位的順序哦。這個例子就能夠說明這個問題:
[rocrocket@rocrocket programming]$ who|cut -b 8,3-5
croe
croe
croe
(5) 還有哪些相似「3-5」這樣的小技巧,列舉一下吧!
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
[rocrocket@rocrocket programming]$ who|cut -b -3
roc
roc
roc
[rocrocket@rocrocket programming]$ who|cut -b 3-
crocket :0 2009-01-08 11:07
crocket pts/0 2009-01-08 11:23 (:0.0)
crocket pts/1 2009-01-08 14:15 (:0.0)
想必你也看到了,-3表示從第一個字節到第三個字節,而3-表示從第三個字節到行尾。若是你細心,你能夠看到這兩種狀況下,都包括了第三個字節「c」。
若是我執行who|cut -b -3,3-,你以爲會如何呢?答案是輸出整行,不會出現連續兩個重疊的c的。看:
[rocrocket@rocrocket programming]$ who|cut -b -3,3-
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
(6)給個以字符爲定位標誌的最簡單的例子吧!
下面例子你似曾相識,提取第3,第4,第5和第8個字符:
[rocrocket@rocrocket programming]$ who|cut -c 3-5,8
croe
croe
croe
不過,看着怎麼和-b沒有什麼區別啊?莫非-b和-c做用同樣? 其實否則,看似相同,只是由於這個例子舉的很差,who輸出的都是單字節字符,因此用-b和-c沒有區別,若是你提取中文,區別就看出來了,來,看看中文提取的狀況:
[rocrocket@rocrocket programming]$ cat cut_ch.txt
星期一
星期二
星期三
星期四
[rocrocket@rocrocket programming]$ cut -b 3 cut_ch.txt
�
�
�
�
[rocrocket@rocrocket programming]$ cut -c 3 cut_ch.txt
一
二
三
四
看到了吧,用-c則會以字符爲單位,輸出正常;而-b只會傻傻的以字節(8位二進制位)來計算,輸出就是亂碼。
既然提到了這個知識點,就再補充一句,若是你學有餘力,就提升一下。
當遇到多字節字符時,可使用-n選項,-n用於告訴cut不要將多字節字符拆開。例子以下:
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -b 2
�
�
�
�
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 2
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 1,2,3
星
星
星
星
(7)域是怎麼回事呢?解釋解釋:)
爲何會有「域」的提取呢,由於剛纔提到的-b和-c只能在固定格式的文檔中提取信息,而對於非固定格式的信息則一籌莫展。這時候「域」就派上用場了。若是你觀察過/etc/passwd文件,你會發現,它並不像who的輸出信息那樣具備固定格式,而是比較零散的排放。可是,冒號在這個文件的每一行中都起到了很是重要的做用,冒號用來隔開每個項。
咱們很幸運,cut命令提供了這樣的提取方式,具體的說就是設置「間隔符」,再設置「提取第幾個域」,就OK了!
以/etc/passwd的前五行內容爲例:
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1
root
bin
daemon
adm
lp
看到了吧,用-d來設置間隔符爲冒號,而後用-f來設置我要取的是第一個域,再按回車,全部的用戶名就都列出來了!呵呵 有成就感吧!
固然,在設定-f時,也可使用例如3-5或者4-相似的格式:
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5,7
root:0:0:root:/bin/bash
bin:1:1:bin:/sbin/nologin
daemon:2:2:daemon:/sbin/nologin
adm:3:4:adm:/sbin/nologin
lp:4:7:lp:/sbin/nologin
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f -2
root:x
bin:x
daemon:x
adm:x
lp:x
(8)若是遇到空格和製表符時,怎麼分辨呢?我以爲有點亂,怎麼辦?
有時候製表符確實很難辨認,有一個方法能夠看出一段空格究竟是由若干個空格組成的仍是由一個製表符組成的。
[rocrocket@rocrocket programming]$ cat tab_space.txt
this is tab finish.
this is several space finish.
[rocrocket@rocrocket programming]$ sed -n l tab_space.txt
this is tab\tfinish.$
this is several space finish.$
看到了吧,若是是製表符(TAB),那麼會顯示爲\t符號,若是是空格,就會原樣顯示。
經過此方法便可以判斷製表符和空格了。
注意,上面sed -n後面的字符是L的小寫字母哦,不要看錯。
(9)我應該在cut -d中用什麼符號來設定製表符或空格呢?
其實cut的-d選項的默認間隔符就是製表符,因此當你就是要使用製表符的時候,徹底就能夠省略-d選項,而直接用-f來取域就能夠了。
若是你設定一個空格爲間隔符,那麼就這樣:
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
this
this
注意,兩個單引號之間可確實要有一個空格哦,不能偷懶。
並且,你只能在-d後面設置一個空格,可不準設置多個空格,由於cut只容許間隔符是一個字符。
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
cut: the delimiter must be a single character
Try `cut --help' for more information.