shell中的几个常用命令
本文为[1]书中内容简要总结。
1 xargs
语法
command | xargs
xargs 将stdin接收到的命令重新格式化,然后再讲解作为参数提供给其他命令。
将多行输入变为单行
cat example.txt | xargs
将单行变多行
cat example.txt | xargs -n 3
每行三个元素
定界符分隔参数
echo "splitXsplitXsplitXsplitX" | xargs -d X
(2)结合find使用xargs
find . -type f -name "*.txt" -print0 | xargs =o rm -f
xargs -0 将\0当作输入定界符
2 sed
(1)sed可以替换给定文本中的字符串,利用正则表达式匹配
sed 's/pattern/replace_string/' file
将结果直接应用于原文件
sed 's/text/replace/' file > newfile
mv newfile file
或者
sed -i 's/text/replace/' file
替换所有内容,我们需要在命令行尾部加入/g
sed 's/pattern/replace_string/g' file
有时候我们不需要替换前N-1处匹配,二是需要替换剩下的匹配。
echo this thisthisthis | sed 's/this/THIS/2g'
Mac 下命令有误,ubuntu可以,可能我用的shell不同
(2)移出空白行
sed '/^$/d' file
/pattern/d 会移出匹配样式的行
(3)已匹配字符串标记&
echo this is an example | sed 's/\w\+/[&]/g'
(4)子串匹配标记\1
echo this is digit 7 in number | sed 's/digit \([0-9]\)/\1/'
(5)引用
text=hello
echo hello world | sed "s/$text/HELLO/"
sed表达式中引用变量字符串的时候,可以使用双引号
3 awk
(1)awk脚本的结构基本如下所示:
awk ' BEGIN{ print "start" } pattern {commands} END{print "END"}'
file
(2)awk命令的工作方式如下:
- 执行
BEGIN{ commands }
语块中的语句。 - 从文件或者stdin中读取一行,然后执行
pattern { commands }
。重复这个过程,直到文件全部读取完毕。 - 当读至输入流末尾时,执行
END { commands }
语句块。
例子: 统计代码
find ~/Documents/Python/MxShop-master -type f -name "*.py" -print0 | xargs -0 wc -l | awk '{sum+=$1}END{print sum}'
64540
(3) 特殊变量
NR: 表示记录数量,在执行过程中相当于当前行号
NF: 表示字段数量,在执行过程中相当于当前行的字段数
$0: 这个变量包含执行过程中当前行的文本内容
$1: 这个变量包含执行过程中第一个字段(第一列)的文本内容
$2: 这个变量包含执行过程中第二个字段(第二列)的文本内容
例子:
echo -e "line1 f2 f3 \nline2 f4 f5 \nline3 f6 f7" | \
awk '{print "Line no:" NR ", No of fields:" NF, "$0=" $0, "$1=" $1, "$2=" $2, "$3=" $3}'
打印每一行的第2和第3个字段:
awk '{ print $3,$2 }' file
统计文件中的行数:
awk 'END {print NR}' file
(4)将外部变量值传递给awk
当输入来自于文件的时候
awk '{print v1,v2 }' v1=$var1,v2=$var2 filename
(5)用geline读取行
grep 默认读取一个文件中的所有行,如果只想读取某一行,可以使用getline函数读取某一行,有时候我们需要从BEGIN语句中读取第一行
seq 5 | awk 'BEGIN {getline; print "Read ahead first line", $0} {print $0}'
(6)用样式对awk处理的行进行过滤
awk 'NR<5'
awk 'NR==1,NR==4'
awk '/linux/'
awk '1/linux/'
(7)设置字段定界符
默认的字段定界符是空格
awk -F: '{ print $NF }' /etc/passwd
awk '{BEGIN{FS=":"} print $NF }' /etc/passwd
(8)在awk中使用循环
awk 'BEGIN {for(i=0;i<10;i++) print i}'
awk 'BEGIN {for(i in array) print i}'
4 grep
(1)语法
grep match_pattern filename
使用正则表达式的时候可以
grep -E "[a-z]+"
egrep "[a-z]+"
只输出匹配到的行:
echo this is a line. | grep -o -E "[a-z]+\."
echo this is a line. | grep -o "[a-z]+\."
统计文件中匹配字符串的行数
grep -c "text" filename
打印包含匹配字符串的行数
grep linux -n sample1.txt sample2.txt
打印样式匹配所位于的字符或字节偏移:
echo gnu is not unix | grep -b -o "not"
找出匹配文本位于哪一个文件中
grep -l linux sample1.txt sample2.txt
(2)递归搜索
grep "test_function()" . -R -n
(3)忽略样式中的大小写
echo hello world | grep -i "HELLO"
(4)grep 匹配多个样式
grep -e "pattern1" -e "pattern2"
(5)grep 搜索中包括或排除文件
grep "main" . -r --include *.{c,cpp}
(6)打印出匹配文本之前或者之后的行
之后几行
seq 10 | grep 5 -A 3
之后几前
seq 10 | grep 5 -B 3
之前之后几行
seq 10 | grep 5 -C 3
[1]Linux Shell 脚本攻略