逐步积累的常用shell整理

Linux shell 学习是一个循序渐进的过程。最开始我是通过《鸟哥的linux私房菜》学习Linux的同时学习了 shell, 入门之后就一直是遇到问题、搜索问题、总结问题的学习过程。

后来感觉一些不错的命令,汇总起来方便后续的查找,于是慢慢的积累了几十条常用的命令,取之于网络,用之于网络,希望对大家有所帮助!


一、删除换行符

cat 文件名|tr -d '\n'
cat 文件名|tr -d '\r'    #可以删除"^M"
cat 文件名|sed ':1;N;s/\n//;t1' 【使用sed删除换行】

二、将linux文件中的tab更换为空格的三种方法

1,用sed命令
#sed ‘s/\t/ /g’ filename >filename1
2,  用tr命令
#cat filename|tr  "\t" " " >filename2
3,用col -x命令
#cat filename|col -x >filename2
扩展阅读: http://blog.sina.com.cn/s/blog_53a173560101ao2p.html

将多个空格替换成逗号
head a.txt |sed 's/ \+/,/g' 【 + 需要转义】
head a.txt |sed 's/  */,/g' 【 * 表示0个或任意多个字符】
’+‘  这是匹配前面的空格(\s)一次或者多次。  意义同 \s \s* 。
扩展阅读: http://bbs.linuxtone.org/thread-17848-1-1.html

三、通过开始行和结束行,查找指定数据

[ymm@EVERSEC temp]$ cat a.txt
  1 dirty data
  2 dirty data
  3 ======
  4 I want these data
  5 I want these data
  6 ======
  7 dirty data
  8 dirty data
  9 ======
 10 I want these data
 11 ======
[ymm@EVERSEC temp]$ sed -n '/======/,/======/p' a.txt
  3 ======
  4 I want these data
  5 I want these data
  6 ======
  9 ======
 10 I want these data
 11 ======
[ymm@EVERSEC temp]$
sed -n '/开始字符串/,/结束字符串/p' 文件名

四、shell中的分组

[root@ tmp]# cat a.txt
a 200 123
a 12 32
a 32 3
b 1200 aaa
b 1 22
b 22 22
c 333 333
d 222 333

#分组求和
[root@ tmp]# cat a.txt |awk '{a[$1]+=$2}END{for(i in a)print i,a[i]}'
a 3
b 3
c 1
d 1

#统计数目
[root@ tmp]# cat a.txt |awk '{a[$1]++}END{for(i in a)print i,a[i]}'
a 244
b 1223
c 333
d 222

#分组求最大值
[root@ tmp]# cat a.txt |awk '{max[$1]=max[$1]>$2?max[$1]:$2}END{for(i in max)print i,max[i]}'
a 200
b 1200
c 333
d 222

#简单的按列求和
[linux@test /tmp]$ cat test
123.52
125.54
126.36

[linux@test /tmp]$ awk '{sum += $1};END {print sum}' test
375.42

扩展阅读: http://bbs.chinaunix.net/thread-1511070-1-1.html
           http://www.5iops.com/html/2013/script_0418/267.html
         http://www.linuxsong.org/2010/09/shell-column-sum/

五、查找包含某字符串的行及后续行

sed -n '/xxxx/{p;n;p}' a.log
查找文件“a.log”中包含“xxxx”的行后续一行。n表示下一行,p表示打印。

六、grep的高级用法:

Context Line Control
    -A NUM, --after-context=NUM
           Print NUM lines of trailing context after matching lines.  Places a line containing a
           group  separator  (--)  between  contiguous  groups  of  matches.   With  the  -o  or
           --only-matching option, this has no effect and a warning is given.

    -B NUM, --before-context=NUM
           Print NUM lines of leading context before matching lines.  Places a line containing a
           group  separator  (--)  between  contiguous  groups  of  matches.   With  the  -o  or
           --only-matching option, this has no effect and a warning is given.

    -C NUM, -NUM, --context=NUM
           Print  NUM  lines of output context.  Places a line containing a group separator (--)
           between contiguous groups of matches.  With the -o or  --only-matching  option,  this
           has no effect and a warning is given.

-A NUM    显示包含的字符串和下面的NUM行数据
-B NUM    显示包含的字符串和上面的NUM行数据
-C NUM    显示包含的字符串及上面和下面的NUM行数据

七、指定文件大小和

使用"ls * |du -sh" 得到的结果其实是当前目录的总大小,如果希望得到指定文件的总大小,应该通过如下方式:
[root@localhost tmp]# ls *txt |xargs du -csh
12K     findex2txt
12K     fwlog2txt
24K     total
[root@localhost tmp]# ls *txt |xargs du -csh|grep total|cut -f1        #过滤得到文件总大小
24K
[root@localhost tmp]#
扩展阅读: http://blog.csdn.net/michaelpp/article/details/12998205

八、解压文件汇总

总结
1、*.tar 用 tar –xvf 解压
2、*.gz 用 gzip -d或者gunzip 解压
3、*.tar.gz和*.tgz 用 tar –xzf 解压
4、*.bz2 用 bzip2 -d或者用bunzip2 解压
5、*.tar.bz2用tar –xjf 解压
6、*.Z 用 uncompress 解压
7、*.tar.Z 用tar –xZf 解压
8、*.rar 用 unrar e解压
9、*.zip 用 unzip 解压
扩展阅读: http://www.jb51.net/LINUXjishu/43356.html

九、sed插入空行

满足某种条件的前面插入插入空行
[root@EVERSEC ~]# ymm="yangmingming"
[root@EVERSEC ~]# echo $ymm
yangmingming
[root@EVERSEC ~]# echo $ymm|sed "/yang/i\\"
yangmingming
[root@EVERSEC ~]# echo $ymm|sed '/yang/i\\'

yangmingming
[root@EVERSEC ~]#
扩展阅读: http://bbs.chinaunix.net/thread-4056672-1-1.html

十、获取除最后一列的其他列数据

NF代表:浏览记录的域的个数
[root@EVERSEC in]# echo "yang ming ming" |awk 'NF--{print $0}'   
yang ming
[root@EVERSEC in]# echo "yang,ming,ming" |awk 'NF--{print $0}'  

[root@EVERSEC in]# echo "yang ming,ming" |awk 'NF--{print $0}'
yang
[root@EVERSEC in]# echo "yang ming,ming" |awk 'BEGIN{FS=OFS=","}NF--{print $0}'
yang ming
[root@EVERSEC in]# echo "yang ming,ming" |awk 'BEGIN{FS=OFS=","}NF--'          
yang ming
[root@EVERSEC in]#

十一、检索异常的'\r'

cat *.txt |awk '/\r[^\n]/'
注:需要排除结尾'\r\n'的情况

十二、打印文件的偶数行

sed '1d;n;d'
sed -n 'n;p'
sed -n '0~2p'
awk '!(NR%2)'
awk 'i++%2'
awk '!(i=i?0:1)'
awk '!(i=!i)'
扩展阅读: http://www.dewen.io/q/797/怎样用shell命令输出日志文件内偶数行?

十三、一行数据拆分成数组

awk '
    BEGIN{
        i=1
    }
    {
        n = split($0, a, "|" );
        while(i<=n){
            print a[i];
            i++;
        }
    }'

十四、sed正则表示式支持

-r, --regexp-extended
       use extended regular expressions in the script.
[root@EVERSEC tmp]# cat -n a.txt
     1  yang|ming
     2  yang
     3  ming
[root@EVERSEC tmp]# cat -n a.txt |sed -n '/yang|ming/p'   
     1  yang|ming
[root@EVERSEC tmp]# cat -n a.txt |sed -r -n '/yang|ming/p'
     1  yang|ming
     2  yang
     3  ming
[root@EVERSEC tmp]#

十五、删除异常“M-BM- ”字符

使用vim中的“set list”显示的都是空格,但是,使用cat查看的结果是“M-BM- ”
[root@EVERSEC tmp]# cat a.txt    
function a_sub {
  sleep 3
}
[root@EVERSEC tmp]# cat -A a.txt
functionM-BM- a_subM-BM- {$
  sleepM-BM- 3$
}$
[root@EVERSEC tmp]#
[root@EVERSEC tmp]# hexdump -C a.txt
00000000  66 75 6e 63 74 69 6f 6e  c2 a0 61 5f 73 75 62 c2  |function..a_sub.|
00000010  a0 7b 0a 20 20 73 6c 65  65 70 c2 a0 33 0a 7d 0a  |.{.  sleep..3.}.|
00000020

""对应的空格,可以在word中通过输入"Ctrl+Shift+Space"输入,对应的十六进制为"0xc2 0xa0",所以可以通过sed的方式删除,如下:
[root@EVERSEC tmp]# sed 's/\xc2\xa0/ /g' a.txt |cat -A
function a_sub {$
  sleep 3$
}$
[root@EVERSEC tmp]#
扩展阅读:  http://askubuntu.com/questions/357248/how-to-remove-special-m-bm-character-with-sed

十六、IP的正则表示

"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"

十七、获取最后两列数据

awk 'NR>1{print $(NF-1),$NF}'
扩展阅读: http://bbs.chinaunix.net/thread-706390-1-1.html

十八、多行数据合并成一行

tr -s "\n" " " < test.txt;echo
扩展阅读: http://blog.sina.com.cn/s/blog_4a3c301c0100lqbm.html

十九、shell字符串分割成数组

a="one,two,three,four"
OLD_IFS="$IFS"
IFS=","
arr=($a)
IFS="$OLD_IFS"
for s in ${arr[@]}
do
    echo "$s"
done
arr=($a)用于将字符串$a分割到数组$arr ${arr[0]} ${arr[1]} ... 分别存储分割后的数组第1 2 ... 项 ,${arr[@]}存储整个数组。变量$IFS存储着分隔符,这里我们将其设为逗号 "," OLD_IFS用于备份默认的分隔符,使用完后将之恢复默认。

附加:修改IFS之后,如果希望打印原始的行,需要恢复原始的IFS,不然打印的数据之间会包含空格
a="one,two,three,four"
OLD_IFS="$IFS"
IFS=","
echo $a
IFS="$OLD_IFS"
echo $a

one two three four
one,two,three,four

附加:如果希望使用while循环获取文件中的每一行数据,那么需要修改IFS为换行符,不然,文件内部的空格或者Tab键也会分割字符串。
使用方法【注意使用了"$",并且只能使用单引号】:
IFS=$'\n'

扩展阅读: http://1985wanggang.blog.163.com/blog/static/776383320121745626320/

二十、获取 Shell 脚本自身进程 pid

这里涉及两个指令: 1. $$ :当前 Shell 进程的 pid 2. $! :上一个后台进程的 pid 可以使用这两个指令来获取相应的进程 pid。例如,如果需要获取某个正在执行的进程的 pid(并写入指定的文件):
myCommand && pid=$!
myCommand & echo $! >/path/to/pid.file
注意,在脚本中执行 $! 只会显示子 Shell 的后台进程 pid,如果子 Shell 先前没有启动后台进程,则没有输出。
扩展阅读: http://weyo.me/pages/techs/linux-get-pid/

二十一、获取程序的启动时间和运行时间

ps -eo lstart 启动时间  
ps -eo etime   运行多长时间.
 
ps -eo pid,lstart,etime|grep pid
例:ps -eo pid,lstart,etime|grep 4559

显示进程id、启动时间、运行时间、命令,便于通过grep过滤
ps -eo pid,lstart,etime,cmd|grep vim

二十二、awk按照多分隔符分割字符串

awk -F"[@ /t]" '{print $2,$3}' test
以@,空格,Tab键分割test文件的每一行,并输出第二、第三列。

如果希望使用“[]”作为分隔符的话,可以使用下面的方式
awk -F"[][]" '{print $2,$3}' test
扩展阅读: http://blog.csdn.net/hongchangfirst/article/details/25071937

awk默认的分隔符包含一个和多个空格,如果设置多个分隔符的时候,中括号中间的一个空格只能识别出一个空格,如果是多个空格的情况,会认为是多个分隔符,解决办法是让分隔符识别多个空格的情况:
awk -F"[@ /t]+" '{print $2,$3}' test
扩展阅读: http://bbs.51cto.com/thread-1126595-1.html

二十三、ls -l显示年与日时分秒等信息

ls -l --time-style="+%Y-%m-%d %H:%M:%S"
扩展阅读: http://blog.itpub.net/10640532/viewspace-697496/

二十四、控制台显示红色闪烁的文字

echo -e "\033[37;31;5m yangmingming \033[39;49;0m"


二十五、选择特定位数的字符

选择第四位到第七位
[root@EVERSEC in]# echo "yangmingming"|cut -c 4-7
gmin
[root@EVERSEC in]#

二十六、grep比较两个文件的异同

1、统计两个文本文件的相同行
grep -Ff file1 file2

2、统计file2中有,file1中没有的行
grep -vFf file2 file1

扩展阅读: http://hxl2009.blog.51cto.com/779549/677226

二十七、awk根据条件输出到不同文件

cat file.AVL|awk -F "|"  '{if($19 == 0) print $0 >"ymm_0.txt"; else if($19 == 5) print $0 > "ymm_5.txt"}'

扩展阅读: http://bbs.chinaunix.net/thread-538971-1-1.html
awk引用外部变量参见:

二十八、vim删除空行或者注释

删除空行
:g/^$/d

删除空行以及只有空格的行
:g/^\s*$/d

删除以 # 开头或 空格# 或 tab#开头的行
:g/^\s*#/d

扩展阅读: http://www.cnblogs.com/carbon3/p/5915282.html

二十九、sed查找符合条件的记录进行字符替换

crontab删除自启动脚本前面的“#”,例如:
#*/1 * * * *  /etc/eversec/broadband-match/broadband-match-cron.sh

使用sed命令进行替换
sed -i 's/源字符串/目的字符串/g' /var/spool/cron/root
因为路径中包含'/',所以需要转义【转义试了下,麻烦并且没有成功,附加:后来验证是因为*没有转义导致】
网上说可以使用其他字符替换,例如:
sed -i 's:源字符串:目的字符串:g' /var/spool/cron/root【没有成功,附加:后来验证是因为*没有转义导致】
扩展阅读: http://bbs.chinaunix.net/thread-287191-1-1.html

后来发现了一个更好的办法:
sed -i '/broadband-match-cron.sh/s/^#//g' /var/spool/cron/root
先通过查找命令查找指定行,然后删除最前面的“#”,问题搞定。

附加:后来验证可行的笨办法
[root@EVERSEC in]# crontab -l|grep broadband-match-cron.sh
#*/1 * * * *  /etc/eversec/broadband-match/broadband-match-cron.sh

#方法一:"/"转义
[root@EVERSEC in]# crontab -l|grep broadband-match-cron.sh|sed 's/#\*\/1 \* \* \* \*  \/etc\/eversec\/broadband-match\/broadband-match-cron.sh/\*\/1 \* \* \* \*  \/etc\/eversec\/broadband-match\/broadband-match-cron.sh/g'
*/1 * * * *  /etc/eversec/broadband-match/broadband-match-cron.sh
#方法二:替换为%
[root@EVERSEC in]# crontab -l|grep broadband-match-cron.sh|sed 's%#\*/1 \* \* \* \*  /etc/eversec/broadband-match/broadband-match-cron.sh%\*/1 \* \* \* \*  /etc/eversec/broadband-match/broadband-match-cron.sh%g'
*/1 * * * *  /etc/eversec/broadband-match/broadband-match-cron.sh
[root@EVERSEC in]#

三十、指定多行合并成一行

[root@EVERSEC match]# cat a.log
192.168.1.17
down
192.168.1.103
open

[root@EVERSEC match]# cat a.log |awk '{if(NR%2 == 0) print $0; else printf("%s ", $0)}'    
192.168.1.17 down
192.168.1.103 open
[root@EVERSEC match]#
或者:
[root@EVERSEC match]# cat a.log |awk '{if(NR%2 == 0) ORS="\n"; else ORS=" "; print $0}'
192.168.1.17 down
192.168.1.103 open
[root@EVERSEC match]#
扩展阅读: http://www.linuxidc.com/Linux/2013-11/92231.htm

三十一、一句话shell

xargs中的{}也可以和其他字符一起拼成新的字符串使用,cut的用法,也可以去掉最后一个后缀
[root@localhost tmp]# for i in $(seq 1 3); do touch ymm_$i.txt.tmp; done    
[root@localhost tmp]# ls ymm_*
ymm_1.txt.tmp  ymm_2.txt.tmp  ymm_3.txt.tmp

#cut可以截取出指定部分
[root@localhost tmp]# ls ymm_1.txt.tmp |cut -d"." -f1,2
ymm_1.txt
[root@localhost tmp]#

#处理文件
[root@localhost tmp]# ls ymm_*.txt.tmp|cut -d"." -f1,2|xargs -I {} echo {}.tmp {}
ymm_1.txt.tmp ymm_1.txt    
ymm_2.txt.tmp ymm_2.txt
ymm_3.txt.tmp ymm_3.txt
[root@localhost tmp]#

如果文件数目太多的话,xargs可以添加-n1,表示没获取一个文件,就进行处理
xargs -n 1

删除文件的时候,就是因为文件数目太多,直接rm的时候,提示参数太长,所以,通过xargs搭配rm删除文件时,可以指定-n N

三十二、获取公网ip

curl members.3322.org/dyndns/getip
扩展阅读: http://jingyan.baidu.com/article/3c343ff7e2b6830d3779632f.html

三十三、for循环中有空格的处理方式

[root@EVERSEC ~]# cat a.txt
aa bb
cc dd
[root@EVERSEC ~]# for i in $(cat a.txt )
> do
> echo "--$i"
> done
--aa
--bb
--cc
--dd

默认情况下,空格也会作为分隔符

修改方式:
1. 修改分隔符为\n,注,赋值的时候,需要使用单引号
[root@EVERSEC ~]# OLDIFS="$IFS"
[root@EVERSEC ~]# IFS=$'\n'
[root@EVERSEC ~]# for i in $(cat a.txt ); do echo "--$i"; done
--aa bb
--cc dd
[root@EVERSEC ~]# IFS="$OLDIFS"

2. 通过while read line的方式
[root@EVERSEC ~]# cat a.txt |while read line; do echo --$line; done
--aa bb
--cc dd
[root@EVERSEC ~]#

如果是单个txt文件的话,使用下面的方式
while read line;do echo $line; done << file.txt

但是,倘若文件是多个文件,或者压缩的文件,亦或者过滤处理后的文件的操作,上述办法就不可行了。对应的解决方案就是
cat file.txt|grep something |while read line; do echo $line; done

三十四、vim替换引用

vim替换的时候,应用操作
:%s/^\([0-9]\.[0-9].[0-9]\)/### \1/g  
:%s/^\([0-9]\.[0-9]\)/## \1/g  
:%s/^\([0-9]\)/# \1/g  

在正规表达式中使用 \( 和 \) 符号括起正规表达式,即可在后面使用\1、\2 等变量来访问 \( 和 \) 中的内容。

扩展阅读: http://blog.csdn.net/hitlion2008/article/details/7964811
         http://www.cnblogs.com/xuxm2007/p/3566855.html

把空格替换为换行
:% s/ /\r/g

扩展阅读: http://blog.csdn.net/tterminator/article/details/51610778

三十五、查找tab

其实在linux中要正确匹配tab(退格)符有两种方式
1:用 grep  $'\t'       你的文件
2:用 grep '按CTRL+V 键,再按TAB键'      你的文件

扩展阅读: http://www.linuxidc.com/Linux/2011-11/47000.htm

三十六、回退svn

svn status|grep -v "^\?"|awk '{print $2}'|while read i; do svn revert $i; echo $i; done
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值