xargs
xargs 是給命令傳遞參數的一個過濾器,也是組合多個命令的一個工具。
xargs 可以將管道或標准輸入(stdin)數據轉換成命令行參數,也能夠從文件的輸出中讀取數據。
xargs 也可以將單行或多行文本輸入轉換為其他格式,例如多行變單行,單行變多行。
xargs 默認的命令是 echo,這意味着通過管道傳遞給 xargs 的輸入將會包含換行和空白,不過通過 xargs 的處理,換行和空白將被空格取代。
xargs 能夠捕獲一個命令的輸出,然后傳遞給另外一個命令。
之所以能用到這個命令,關鍵是由於很多命令不支持|管道來傳遞參數,而日常工作中有有這個必要,所以就有了 xargs 命令,例如:
find /sbin -perm +700 |ls -l #這個命令是錯誤的 find /sbin -perm +700 |xargs ls -l #這樣才是正確的
xargs 一般是和管道一起使用。
命令格式:
somecommand |xargs -item command
參數:
- -a file 從文件中讀入作為sdtin
- -e flag ,注意有的時候可能會是-E,flag必須是一個以空格分隔的標志,當xargs分析到含有flag這個標志的時候就停止。
- -p 當每次執行一個argument的時候詢問一次用戶。
- -n num 后面加次數,表示命令在執行的時候一次用的argument的個數,默認是用所有的。
- -t 表示先打印命令,然后再執行。
- -i 或者是-I,這得看linux支持了,將xargs的每項名稱,一般是一行一行賦值給 {},可以用 {} 代替。
- -r no-run-if-empty 當xargs的輸入為空的時候則停止xargs,不用再去執行了。
- -s num 命令行的最大字符數,指的是 xargs 后面那個命令的最大命令行字符數。
- -L num 從標准輸入一次讀取 num 行送給 command 命令。
- -l 同 -L。
- -d delim 分隔符,默認的xargs分隔符是回車,argument的分隔符是空格,這里修改的是xargs的分隔符。
- -x exit的意思,主要是配合-s使用。。
- -P 修改最大的進程數,默認是1,為0時候為as many as it can ,這個例子我沒有想到,應該平時都用不到的吧。
例子:
cat test.txt | xargs -n 3 #將單行划分為多行,每行3個字
echo "splitxsplitxsplitxsplitx" | xargs -d x #使用-d將x作為輸入定界符(默認是使用IFS作為輸入定界符的)
echo "splitxsplitxsplitxsplitx" | xargs -d x -n 2 #將以上結果划分成多行,每行2個字
cat args.txt | xargs -n 2 ./test.sh #將參數寫在args.txt中,每次可以修改-n的數字選擇傳多少個參數給腳本test.sh
cat args.txt | xargs -I {} ./test.sh -p {} -l #從args.txt讀取參數,腳本test.sh每次需要傳入3個參數,中間的參數為不固定的
cat files.txt | xargs -I {} cat {} #將接收到的參數打印出來
cat files.txt | ( while read arg; do $arg; done ) #同上
redis-cli KEYS "pattern" | xargs redis-cli DEL #通過模糊匹配pattern正則,刪除對應的redis鍵值對
redis-cli -a password KEYS "godel*" | xargs redis-cli -a password DEL #同上, -a參數指定密碼
注意:將命令輸出作為xargs命令的輸入的時候,最好為輸出的各行添加一個0值字節終止符。xargs默認是使用空格最為定界符分割參數的。這樣的話如果傳入的單行輸出中包含空格,那么會被以空格分割成多個參數。例如"This is test"傳入xargs時,會被默認分割成3個參數。如果用0值字節終止符,那么\0就被作為定界符,此時,包括空格的單行就能正確地解析為單個參數了。所以在用的時候先加-0參數再加其他參數:xargs -0 ...
grep
語法:
grep [-abcEFGhHilLnqrsvVwxy][-A<顯示列數>][-B<顯示列數>][-C<顯示列數>][-d<進行動作>][-e<范本樣式>][-f<范本文件>][--help][范本樣式][文件或目錄...]
參數:
- -a 或 --text : 不要忽略二進制的數據。
- -A<顯示行數> 或 --after-context=<顯示行數> : 除了顯示符合范本樣式的那一列之外,並顯示該行之后的內容。
- -b 或 --byte-offset : 在顯示符合樣式的那一行之前,標示出該行第一個字符的編號。
- -B<顯示行數> 或 --before-context=<顯示行數> : 除了顯示符合樣式的那一行之外,並顯示該行之前的內容。
- -c 或 --count : 計算符合樣式的列數。
- -C<顯示行數> 或 --context=<顯示行數>或-<顯示行數> : 除了顯示符合樣式的那一行之外,並顯示該行之前后的內容。
- -d <動作> 或 --directories=<動作> : 當指定要查找的是目錄而非文件時,必須使用這項參數,否則grep指令將回報信息並停止動作。
- -e<范本樣式> 或 --regexp=<范本樣式> : 指定字符串做為查找文件內容的樣式。
- -E 或 --extended-regexp : 將樣式為延伸的普通表示法來使用。
- -f<規則文件> 或 --file=<規則文件> : 指定規則文件,其內容含有一個或多個規則樣式,讓grep查找符合規則條件的文件內容,格式為每行一個規則樣式。
- -F 或 --fixed-regexp : 將樣式視為固定字符串的列表。
- -G 或 --basic-regexp : 將樣式視為普通的表示法來使用。
- -h 或 --no-filename : 在顯示符合樣式的那一行之前,不標示該行所屬的文件名稱。
- -H 或 --with-filename : 在顯示符合樣式的那一行之前,表示該行所屬的文件名稱。
- -i 或 --ignore-case : 忽略字符大小寫的差別。
- -l 或 --file-with-matches : 列出文件內容符合指定的樣式的文件名稱。
- -L 或 --files-without-match : 列出文件內容不符合指定的樣式的文件名稱。
- -n 或 --line-number : 在顯示符合樣式的那一行之前,標示出該行的列數編號。
- -q 或 --quiet或--silent : 不顯示任何信息。
- -r 或 --recursive : 此參數的效果和指定"-d recurse"參數相同。
- -s 或 --no-messages : 不顯示錯誤信息。
- -v 或 --revert-match : 顯示不包含匹配文本的所有行。
- -V 或 --version : 顯示版本信息。
- -w 或 --word-regexp : 只顯示全字符合的列。
- -x --line-regexp : 只顯示全列符合的列。
- -y : 此參數的效果和指定"-i"參數相同。
例子:
grep match_pattern filename #在文件中搜索一個單詞 match_pattern多為通配符或正則表達式
grep "match_pattern" filename #同上
grep -E "[a-z]+" file #要匹配正則則表達式需要加參數-E
egrep "[a-z]+" file #可以匹配正則表達式的搜索
grep -c "text" filename #統計文本中包含匹配字符串的行數,參數-c只是統計匹配行的數量,並不是匹配的次數
grep word filename --color=auto #在輸出行中重點標記出匹配到的單詞
grep -f pattern_file source_filename #使用參數-f也是用於指定多個樣式
grep "main()" /data -r --include *.{c,cpp} #只在/data目錄中遞歸搜索所有的.c和.cpp文件
grep "main()" /data -r --exclude "README" #在搜索中排除所有的README文件,如果要排序目錄則使用 --exclude-dir,如果要從文件中讀取所需排除的列表則使用--exclude-from FILE
grep -v test filename #打印不包含test的所有行, 參數-v表示對包含某個字段進行過濾排除
grep "match_pattern" file1 file2 file3... #對多個文件進行搜索
grep linux -n test.txt test2.txt #參數-n是匹配結果行與其所屬文件名一並打印出來
echo gnu is not unix | grep -b -o "not" #打印樣式匹配所位於的字符或字節偏移,偏移量起始值為0,即該行第一個字符。-b和-o參數是配合使用的
grep -l linux test1.txt test2.txt #搜索過個文件並找出匹配文本位於哪個一個文件中,相反的選項有-L,它會返回一個不匹配的文件列表
grep "match_pattern" . -R -n #從當前目錄開始,在多級目錄中對文本進行遞歸搜索
echo hello world | grep -i "HELLO" #輸出hello ,參數-i表示在匹配時不區分大小寫
echo this is a line. | grep -o -E "[a-z]+\." #結果:line. 參數-o表示只輸出文件中匹配到的文本部分
echo this is a line of text | grep -e "this" -e "line" -o #使用參數-e來指定匹配多個樣式
seq 10 | grep 5 -A 3 #參數-A打印5以及之后3行,也就是5,6,7,8
seq 10 | grep 5 -B 3 #參數-B打印5以及之前3行,也就是2,3,4,5
seq 10 | grep 5 -C 3 #參數-C打印5以及之前和之后3行,也就是2,3,4,5,6,7,8
look word filepath #列出文件中以特定單詞起頭的所有單詞,如果沒有給出文件參數,look命令會使用默認詞典/usr/share/dict/words
grep "^word" filepath #同上
grep '^$' /mydata/test*.log | wc -l #查詢mydata目錄下test開通的log文件中空行數
腳本例子1:測試文件是否包含特定的文本內容
#!/bin/bash
#filename:test.sh
#執行:test.sh student test_data.txt
if [ $# -ne 2 ];
then
echo "$0 match_text filename"
fi
match_text=$1
filename=$2
grep -q $match_text $filename #參數-q使grep進入靜默模式,只返回0或非0值,不會打印其他輸出
if [ $? -eq 0 ]
then
echo "The text exists in the file"
else
echo "The text not exists in the file"
fi
腳本例子2:統計特定文件中的詞頻
#!/bin/bash
#文件名:test.sh
#執行:test.sh words.txt
if [ $# -ne 1 ];
then
echo "Usage:$0 filename";
exit -1
fi
filename=$1
egrep -o "\b[[:alpha:]]+\b" $filename | \
awk '{ count[$0]++}
END{ printf{"%-14s%s\n","Word","Count"};
for(ind in count)
{ printf("%-14s%d\n",ind,count[ind]); }
}'
腳本例子3:拼寫檢查與詞典操作
法一:
#!/bin/bash
#filename:test.sh
word=$1
grep '^$1$' /usr/share/dict/brithish-english -q #查找傳入的參數是否在字典/usr/share/dict/brithish-english中。 ^表示正則的單詞開頭,$表示單詞結尾,-q禁止產生任何輸出
if [ $? -eq 0 ] ;then
echo $word is a dictionary word;
else
echo $word is not a dictionary word;
fi
法二:
#!/bin/bash
#filename:test.sh
word=$1
output=`echo \"$word\" | aspell list` #當給定的輸入不是一個詞典單詞時,aspell list命令將產生輸出文本,反之則不產生任何輸出。-z用於確認
if [ -z $output ] ;then
echo $word is a dictionary word;
else
echo $word is not a dictionary word;
fi
-------------------------------------------------