linux shell常用脚本命令

sed用法

  1. 打印第n行到最后一行的内容
    sed -n ‘1673523, $p’ bs.gi.log > /home/work/qhl/bs.gi.log

  2. 打印匹配abc的行到最后一行的内容。
    sed -n ‘/abc/,$p’ file.txt
    注意是单引号

  3. 匹配特定字符串
    1
    echo $line | sed 's/pattern//g'

eg

1
echo 'DB_TYPE_ARR1: rts-weibo:0.80, dnews-weibo:0.80' |grep DB_TYPE_ARR | sed 's/DB_TYPE_ARR//' | sed 's/:[0-9].[0-9]\+//g'

注意,g是全部替换的意思

  1. 替换换行
    1
    sed ':a;N;$!ba;s/\n/ /g'

示例追加:

1
2
$ echo -e "1\n2" | sed ':a;N;$!ba;s/\n/ /g'
1 2

  1. 替换某个字符串
    将某个文件中的jack字符串替换为tom

    1
    sed -i "s/jack/tom/g" test.txt
  2. 如果替换字符串中有”/“的替换
    要使用#来替换

    1
    sed -i 's#origin/string#newstring#g'file_name

eg 如果一个路径是data/path/abc,现在要将此路径换成一个字符串cde

1
sed -i 's#data/path/abc#cde#g' file_name

  1. shell awk删除每行最后10个字符
    1
    2
    3
    4
    #!/bin/ksh
    . ~/.profile

    awk '{sub(/.{10}$/,"")}1' test.unl

shell 10进制转16进制

1
echo 10 | awk '{printf ("%x\n", $0)}'

tar 用法

  1. 打包排除某些文件或文件夹
    tar -zcvf test.tar.gz -X exclude.list test/
    其中exclude.list里面包含了那些你不想要的文件或是文件夹
    tar排除某些文件或文件夹

字符串前面补0

start=printf "%02d" "$i"

shell for循环

for ((i=0; i<60; i++));
do
echo $i;
done

vim配置

vim配置显示中文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
syntax on
filetype indent plugin on
set modeline
set tabstop=4
set expandtab
set softtabstop=4
set shiftwidth=4
set nonumber
set cmdheight=1
set laststatus=2
set fileencodings=utf-8,gb2312,gb18030,gbk,ucs-bom,cp936,latin1
set enc=utf8
set fencs=utf8,gbk,gb2312,gb18030
map <F4> <Esc>:%!python -m json.tool<CR>
set number
set expandtab ts=4 sw=4 sts=4 tw=100

copy文件

1
rsync -avnL twemproxy --exclude=twemproxy/log work@host.com:/home/work/scp_tmp

-avnL: 显示哪些要被copy,但是实际上并未执行copy,-avL是真的copy

随机数生成

使用系统的 $RANDOM 变量

1
echo $RANDOM

$RANDOM 的范围是 [0, 32767]

  • 想生成2~10范围之间的随机数
    1
    echo $(($RANDOM%9+2))

获取函数的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
function test() {
RET_VALUE=15
res=17
return 1
}

function test1() {
test
echo ${RET_VALUE}
echo ${res}
}

test1

如上代码会输出 15,17. 即通过全局变量的方式来获取函数的返回值

统计文件的大小

1
du * -csh

awk用法

awk 分割之后打印所有的列

1
awk 'BEGIN{RS=""}{for(a=1;a<=NF;a++) print $a}' connext.txt

查看进程系统运行时间

1
ps -eo pid,lstart,etime,cmd | grep nginx

杀进程吐core

1
kill -4 pid

kill -l 可以列出所有的数字信号代表的含义。

nc 命令

nc是netcat的简写,有着网络界的瑞士军刀美誉。因为它短小精悍、功能实用,被设计为一个简单、可靠的网络工具

nc的作用

  • (1)实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口

  • (2)端口的扫描,nc可以作为client发起TCP或UDP连接

  • (3)机器之间传输文件

  • (4)机器之间网络测速

eg:开启http服务监听12345端口

1
nc -l -p 12345

挂在分区,mount,umount分区

  1. 查看已挂载分区和文件系统类型
    1
    df -T

Filesystem Type 1K-blocks Used Available Use% Mounted on
/dev/sda1 ext4 20642428 3698868 15894984 19% /
tmpfs tmpfs 32947160 0 32947160 0% /dev/shm

  1. 格式化分区

    1
    sudo mkfs -t ext4 /dev/sde1
  2. 挂载分区

    1
    sudo mount -t ext4 /dev/sde1 /home/ssd1/

grep 命令

grep 正则某些字段,并且把其输出为同一行

有如下数据

1
2
3
4
id=13 name=xiaoming age=35
id=15 name=zhangsan age=33
id=17 name=lisi age=31
id=45 name=wangwu age=25

  1. 把grep出的两行合并为1行
    1
    grep -oP "(id=\d+)|(name=.+? )" info.txt

输出如下

1
2
3
4
5
6
7
8
id=13
name=xiaoming
id=15
name=zhangsan
id=17
name=lisi
id=45
name=wangwu

如下命令可以让其输出为一行数据

1
grep -oP "(id=\d+)|(name=.+? )" info.txt | sed 'N; s/\n/ /g'

输出如下

1
2
3
4
id=13 name=xiaoming
id=15 name=zhangsan
id=17 name=lisi
id=45 name=wangwu

  1. 把grep出的三行合并为1行
    命令
    1
    grep -oP "(id=\d+)|(name=.+? )|(age=\d+)" info.txt

输出

1
2
3
4
5
6
7
8
9
10
11
12
id=13
name=xiaoming
age=35
id=15
name=zhangsan
age=33
id=17
name=lisi
age=31
id=45
name=wangwu
age=25

命令

1
grep -oP "(id=\d+)|(name=.+? )|(age=\d+)" info.txt | sed 'N;N;s/\n/ /g'

输出

1
2
3
4
id=13 name=xiaoming  age=35
id=15 name=zhangsan age=33
id=17 name=lisi age=31
id=45 name=wangwu age=2

也可以用 ‘\t’ 来替换

1
grep -oP "(id=\d+)|(name=.+? )|(age=\d+)" info.txt | sed 'N;N;s/\n/\t/g

取出某个字符串后面的字符

Can grep output only specified groupings that match?
假设有如下文件,想取出foobar后面的字符串

1
2
3
4
5
# file: 'test.txt'
foobar bash 1
bash
foobar happy
foobar

1
2
3
4
5
6
7
8
9
10
11
12
13
sed -n "s/^.*foobar\s*\(\S*\).*$/\1/p"

-n suppress printing
s substitute
^.* anything before foobar
foobar initial search match
\s* any white space character (space)
\( start capture group
\S* capture any non-white space character (word)
\) end capture group
.*$ anything after the capture group
\1 substitute everything with the 1st capture group
p print it

如何批量添加一行内容到某些文件的末尾?

答:先使用find找出要指定的某些文件,然后使用xargs和sed工具将内容插入到这些文件的末尾

1
find . -name 'filename*' | xargs sed -i '$a\added-content'

Argument list too long error for rm, cp, mv commands

The reason this occurs is because bash actually expands the asterisk to every matching file, producing a very long command line.

Try this:

1
find . -name "*.pdf" -print0 | xargs -0 rm

Warning: this is a recursive search and will find (and delete) files in subdirectories as well. Tack on -f to the rm command only if you are sure you don’t want confirmation.

You can do the following to make the command non-recursive:

1
find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

Another option is to use find’s -delete flag:

1
find . -name "*.pdf" -delete

Argument list too long error for rm, cp, mv commands

好的参考资料