一些常用的shell记录下来。
1)查询当前目录下各子目录的总大小 以m为单位
ll|awk '{print $9}'|xargs -i du -m -s {}
2)常用的 sed 命令
1.1 打印从第二行起,到最后一行。 ll |sed -n '2,$p'
解释一下:
因为ll上面会有一行是显示总占用量,一些情况下不需要这行
-n 是必须要加的,不加 所以的会打印一次,符合条件的又打印一次,就是第一行打一次,其它行打两次
1.2 sed 里面的正则式要注意转义
p_path='aa/bb/cc'
sub_path ='/bb/cc'
reg_sub_path=`echo ${sub_path}| sed 's///\\//g' #把斜扛/转为\\/ reg_sub_path 这时为 \/bb\/cc
sed 's/'${reg_sub_path}'//g' #这句功能是去掉了bcc 只剩下aa了,这里相当于 sed 's//bb/cc//g' 因为 ${reg_sub_path}变量转为sed里面的可识别正则字符时对 \进行了一次转义变成了而/并未转义,sed的正则又要通过/来匹配/
1.3 正则的其它注意事项 与 sed的逻辑判断
1) 正则里面的大括号要转义,中括号不用转义
echo aabbccddeeff|sed 's/[^f]{0,}//g'输出 ff
2) 中括号里的^表示出现或不出现,并且^只在第一位时表示所有中括号里的值不出现。
echo aabbccddeeff|sed 's/[^f|b]{0,100}//g' 输出 bbff
3) 或者符需要转义| 逗号不需要转义
echo aabbccddeeff|sed 's/[bcde]{1,1}|[a]{1,1}//g' 输出ff
4) 正则中不存在并且的判断,只有找到或找不到两种结果,或者的意思就是找两次
5) 正则的起^,末$
6) 如果要进行判断就是借用sed 的功能来完成 如 echo aabbccddeeff|sed '/[acb]{0,}/b fun :fun /[cb]{0,}/b fun2 :fun2 s/bc//g' 输出 aabcddeeff
这里有三个条件:
第一个条件成立[acb]{0,} 则找第二个条件 [cb]{0,} 第二个条件成立则找第三个动作,是一个替换命令 s/bc//g
不过要注意的是:这个替换虽然是经过三个条件,但是前面两个是找这整行是否符合这个正则,第三行的条件才是去匹配行内的字符串的。
1.4替换行首行尾
在每行的头添加字符,比如"HEAD",命令如下:
sed 's/^/HEAD&/g' test.file
在每行的行尾添加字符,比如“TAIL”,命令如下:
sed 's/$/&TAIL/g' test.file
1.5在最后一行追加字符
find /e/v.os.sys/* -name *.vmx|xargs -i sed -i '$s/$/ mainMem.useNamedFile=FALSE&/g' {}
2)常用的 awk命令
2.1 awk命令在控制台打印的基本格式是 ll | awk '{ print $9}'
解释一下:
ll后出来的第九列 就是子文件名,这个是最常取的
print $9 就是打印 第九列 ,并且是每一行打印一次
printl $9 则是把所有行汇总再打印一次 这个区别是很重要的
2.2 awk -v 参数
export -f fun 这里是将 shell方法 fun 变成一个系统认识的命令,经过这样定义后系统会把fun 解析成 shell方法的代码放到shell脚本中来调用
ll | awk -v prm1=${imput} -v prm2=$1 '{ cmd="fun prm1 prm2 " system(cmd) }'
解释一下
-v 就是 定义一个在'{}' 里面能够使用的变量
export -f
3) 常用的 xargs -i 命令
3.1 ll | awk '{ print $9}' |xargs -i echo {}
xargs 就是将每行做为一个输入
-i 就是用占位符来代替 {} 就是占位符。
其它一些
行变列,列变行,所有行有相同列数,所有列有相同行数(方阵)
ll|awk '{print $4,$9}'|sed -n '2,10p' #转置前
root app
root bin
root boot
root data
root dev
root dist
root etc
root git.repositories
root home
ll|awk '{print $4,$9}'|sed -n '2,10p' |awk -F " " '{for(i=1;i<=NF;i++) a[i,NR]=$i}END{for(i=1;i<=NF;i++) {{for(j=1;j<=NR;j++) {printf a[i,j] " "}}printf " "}}' |column -t
转置后
root root root root root root root root root
app bin boot data dev dist etc git.repositories home
适用于有固定的域 必须指定有符号分隔才能不乱 这里假定源数据 用逗号分隔
root , app , root
root , bin , root
root , , root
root , data , root
root , dev , root
root , dist , root
,etc , root
root , git.repositories , root
root , home ,
cat info | tr -s [:space:] |awk -F "," '{for(i=1;i<=NF;i++) a[i,NR]=$i}END{for(i=1;i<=3;i++) {{for(j=1;j<=NR;j++) {printf a[i,j]; if(j!=NR){printf","}}}printf " "}}'|column -s ',' -t -o ','
行转列后变成
root ,root ,root ,root ,root ,root , ,root ,root
app , bin , , data , dev , dist ,etc , git.repositories , home
root, root, root, root , root, root , root, root ,
可以用
想将很多行变成一行数据如
周一 ,app ,root
周二 ,bin ,
周三 , ,
周四 ,data , root
周五 , ,
cat info |tr " " "."|sed -e 's/.$/ /'
于是变成了下面的一行,就是以句号换行号,再去掉最后一行的句号
周一 ,app ,root.周二 ,bin ,.周三 , ,.周四 ,data , root.周五 , ,
一行的表示有什么好处呢?可以做为一个参数发送给函数处理
然后 | cut -d "." -f 2
就得到了 原数据的第二行
周二 ,bin ,
然后再 | cut -d "," -f 1
就得到源数据的第一列
单行变一列
这是单行
ll|sed -n '2,2p'
单行
行列互转
| awk -F " " '{for(i=1;i<=NF;i++) a[i,NR]=$i}END{for(i=1;i<=NF;i++) {{for(j=1;j<=NR;j++) {printf a[i,j] " "}}printf " "}}'
当然还可以再加这句转回来,
也可以 单列转行
tr " " " "|sed -e 's/" "$/ /'
奇怪的换行符^M
当文本中出现一些奇怪现像比如用sed替换换行符后 ,还是有换行符的现像出现,这时可能是文本中有^M。
这时有几个方法,第一个cat -A 会打出所有可见字符然后 替换掉,这时是可以用输入方式匹配 ^M
或者直接pai 匹配
vi sed 's/^M//g'` 注意 ^M 使用“CTRL-V CTRL-M”生成,而不是直接键入“^M”
vi 用 命令能显示不可见字符,但是 ^M却不能显示 这就坑了:set invlist
^(?!某字符串).*$