Linux 常用命令(五)

作者:小徐

制作时间:20180601

联系方式:xiaoxubigdata@163.com

18 Linux 高级命令使用

18.1 查找出占用CPU与内存比较高的进程

18.1.1 查看ps进程

# ps -aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.1 44128 6620 ? Ss 10:24 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 24

root 2 0.0 0.0 0 0 ? S 10:24 0:00 [kthreadd]

root 3 0.0 0.0 0 0 ? S 10:24 0:00 [ksoftirqd/0]

******

18.1.2 查找出占用CPU比较高的进程

# ps -aux | sort -rnk 3 | head -n 5

18.1.3 查找出占用比较高的MEM的进程

# ps -aux| sort -rnk 4 |head -n 5

18.2 cp高级命令使用

使用cp快速备份文件

# cp docker.install.sh{,_back}

# ls

docker.install.sh docker.install.sh_back

可以看出以上备份了一个*_back文件,节省了时间

18.3 MV高级命令使用

使用mv快速对文件重命令

# mv docker.install.sh{,_sd}

# ls

docker.install.sh_back

18.4 把doc格式的文件转化为unix

18.4.1 说明

使用win编辑好的文件传向linux上时会有特殊的符号,还有linux平台上行不识别doc格式的文件.

18.4.2 安装及查看帮助

18.4.2.1 安装工具

安装工具dos2unix工具包

# yum install -y dos2unix

18.4.2.2 查看帮助

# dos2unix --help

dos2unix 6.0.3 (2013-01-25)

Usage: dos2unix [options] [file ...] [-n infile outfile ...]

-ascii convert only line breaks (default)

-iso conversion between DOS and ISO-8859-1 character set

-1252 Use Windows code page 1252 (Western European)

-437 Use DOS code page 437 (US) (default)

-850 Use DOS code page 850 (Western European)

-860 Use DOS code page 860 (Portuguese)

-863 Use DOS code page 863 (French Canadian)

-865 Use DOS code page 865 (Nordic)

-7 Convert 8 bit characters to 7 bit space

-c, --convmode conversion mode

convmode ascii, 7bit, iso, mac, default to ascii

-f, --force force conversion of binary files

-h, --help give this help

-k, --keepdate keep output file date

-L, --license display software license

-l, --newline add additional newline

-m, --add-bom add UTF-8 Byte Order Mark

-n, --newfile write to new file

infile original file in new file mode

outfile output file in new file mode

-o, --oldfile write to old file

file ... files to convert in old file mode

-q, --quiet quiet mode, suppress all warnings

always on in stdio mode

-s, --safe skip binary files (default)

-F, --follow-symlink follow symbolic links and convert the targets

-R, --replace-symlink replace symbolic links with converted files

(original target files remain unchanged)

-S, --skip-symlink keep symbolic links and targets unchanged (default)

-V, --version display version number

18.4.3 替换单个与多个文件

18.4.3.1 替换单个文件

aclocal.m4 是需要替换的文件

# dos2unix aclocal.m4

dos2unix: converting file aclocal.m4 to Unix format ...

18.4.3.2 替换多个文件

一下命令可以替换/home/xiaoxu/greeplum/gpdb文件下的全部文件,*代表所有文件

# find /home/xiaoxu/greeplum/gpdb -name "*" | xargs dos2unix

*********************

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/src/tutorial/Makefile to Unix format ...

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/src/tutorial/README to Unix format ...

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/src/tutorial/syscat.source to Unix format ...

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/src/win32.mak to Unix format ...

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/THIRDPARTY to Unix format ...

dos2unix: converting file /home/xiaoxu/greeplum/gpdb/config.log to Unix format ...

18.4.4 命令行替换文件

# sed -i 's/\r$//g' aaa.txt

18.5 查看文件中最长的长度并倒叙排序

# cat aaa.txt

aaaaaaa

dwdefefef

cddfe&&&&&fefe&&&&fefscdfddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddfffffffffffffffffffffffrrrrrrrrrrrrrrrrrrrrrrrbbbbbbbbbbbbbbbbbbbbwwwwwwwwwwwwwwwwwwwwcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccefreggggggggggg

333&&&&&3

sddefefe

wee33

# awk '{print NR ":" length($1);}' aaa.txt | sort -t ":" -k 2 | head -n 4

3:251

6:5

1:7

5:8

19 Linux高级问题排查

19.1 网络丢包问题排查

19.1.1 问题描述

在web段请求链接的时候经常会显示链接错误或请求时间过长,在请求过程中走的TCP链接,还需要对TCP了解。

19.1.2 排查方法

19.1.2.1 查看网卡的统计信息

安装ifconfig命令

# yum install net-tools -y

# ifconfig

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 192.168.31.100 netmask 255.255.255.0 broadcast 192.168.31.255

inet6 fe80::a00:27ff:fe1a:f5b4 prefixlen 64 scopeid 0x20<link>

ether 08:00:27:1a:f5:b4 txqueuelen 1000 (Ethernet)

RX packets 349250 bytes 77199466 (73.6 MiB)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 25484 bytes 1974427 (1.8 MiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

在以上中可以看出网卡已经把错包和丢包的情况全部统计出来了,其中RX packets为接受的包, TX packets发送的包。

当然你也可以显示详细的统计信息

# ethtool -S enp0s3|grep errors

rx_errors: 0

tx_errors: 0

rx_length_errors: 0

rx_over_errors: 0

rx_crc_errors: 0

rx_frame_errors: 0

rx_missed_errors: 0

tx_aborted_errors: 0

tx_carrier_errors: 0

tx_fifo_errors: 0

tx_heartbeat_errors: 0

tx_window_errors: 0

rx_long_length_errors: 0

rx_short_length_errors: 0

rx_align_errors: 0

rx_csum_offload_errors: 0

如果在以上中看到了errors大于0的值,一般的可以查看网线或网卡等硬件设备出问题了

19.1.3 分析TCP链接问题

19.1.3.1 TCP介绍

TCP 中两个队列分别是 SYN Queue队列和Accept Queue队列,Accept Queue 就是三次握手成功后等待应用 accept() 连接的队列。如果在web段瞬间有大量的请求进入或者是应用 accept() 取出连接的速度太慢,那么这个队列将会溢出,此时系统会根据 tcp_abort_on_overflow 这个内核参数决定是直接丢弃数据包还是发送 RST 给客户端。反映出来的现象就是前端应用无法建立连接。

19.1.3.2查看当前队列的详细信息

用ss命令查看当前队列的大小

# ss -lnt| expand

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 128 *:22 *:*

LISTEN 0 100 127.0.0.1:25 *:*

LISTEN 0 128 :::22 :::*

LISTEN 0 100 ::1:25 :::*

在以上可以看出当前链接的状态,发送包数与接受包数,以及监控的端口,当 Recv-Q 的值接近于 Send-Q 时,就说明当前已完成队列快溢出了,就说明请求的过多了,一直处于等待处理的状态。

19.1.4提高处理能力

19.1.4.1跳动滑动窗口

为了提升服务器的吞吐能力,我们一般都会优化系统的 TCP 缓冲区大小,查看一下的配置大小

# cat /proc/sys/net/ipv4/tcp_rmem

4096 87380 6291456

# cat /proc/sys/net/ipv4/tcp_wmem

4096 16384 4194304

87380 : tcp接收缓冲区的默认值

16384 : tcp 发送缓冲区的默认值

19.1.4.2 tcp 或udp收发缓冲区最大值

# cat /proc/sys/net/core/rmem_max

212992

131071 :tcp 或 udp 接收缓冲区最大可设置值的一半

也就是说调用 setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcv_size, &optlen); 时rcv_size 如果超过 131071,那么getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcv_size, &optlen); 去到的值就等于 131071 * 2 = 262142

# cat /proc/sys/net/core/wmem_max

212992

212992:tcp 或 udp 发送缓冲区最大可设置值得一半。

19.1.4.3 udp收发缓冲区默认值

# cat /proc/sys/net/core/rmem_default

111616:udp接收缓冲区的默认值

# cat /proc/sys/net/core/wmem_default

111616

111616:udp发送缓冲区的默认值

19.1.4.4 tcp 或udp收发缓冲区最小值

tcp 或udp接收缓冲区的最小值为 256 bytes,由内核的宏决定

tcp 或udp发送缓冲区的最小值为 2048 bytes,由内核的宏决定

19.1.5参考资料

https://mp.weixin.qq.com/s/dCkA3Pzt6rHheiCk3kvG6w

https://blog.csdn.net/qiaoliang328/article/details/7580555

19.2 TIME_WAIT 的那些事

19.2.1 描述

我们知道 TCP 在关闭连接的时候,主动断开的一方将处于 TIME_WAIT 状态,并将持续两倍的 MSL。这个 MSL 在 RFC 793 中的建议是 1 分钟,但是很多系统实现都是 30 秒,所以 TIME_WAIT 的时长也就是 1 分钟。这个参数实在内核中设置的,如果想修改需要重新编译内核参数,查看可以使用ss 来查看 TIME_WAIT 的剩余存活时长(netstat 也可以 -o 参数)

19.2.2 查看TIME_WAIT

$ ss -nta -o state TIME-WAIT | cat

Recv-Q Send-Q Local Address:Port Peer Address:Port

0 0 192.168.209.14:10050 192.168.203.91:46113 timer:(timewait,358ms,0)

在以上的参数中可以看出timewait等待的时间为358ms,之后就会被系统回收掉。在一个高性能的系统中,大概会稳定在 200ms 左右,可以通过「ss -int」命令来确认。当然,TCP Timer 除了 TIME_WAIT 这种,还有 KEEPALIVE, ON, OFF 三种类型。

19.2.3 查看KEEPALIVE状态

$ netstat -otn

在以上中可以看出有KEEPALIVE,ON,OFF状态的链接,其中KEEPALIVE并不是代表长连接的意思,而是 TCP 的「保活」机制,当达到这个时间系统便会回收。

KEEPALIVE

这里的 keepalive 可并不是长连接的意思,而是 TCP 的「保活」机制。

ON

就是 RTO 超时重传时间。

OFF

以上三种都不属于。

20 Linux 编程

20.1 常用传值符号

$# 是传给脚本的参数个数

$0 是脚本本身的名字

$1 是传递给该shell脚本的第一个参数

$2 是传递给该shell脚本的第二个参数

$@ 是传给脚本的所有参数的列表

$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个

$$ 是脚本运行的当前进程ID号

$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

20.2 常用判断符号

20.2.1 字符串判断

str1 = str2      当两个串有相同内容、长度时为真

str1 != str2      当串str1和str2不等时为真

-n str1        当串的长度大于0时为真(串非空)

-z str1        当串的长度为0时为真(空串)

str1         当串str1为非空时为真

20.2.2 数字的判断

int1 -eq int2    两数相等为真

int1 -ne int2    两数不等为真

int1 -gt int2    int1大于int2为真

int1 -ge int2    int1大于等于int2为真

int1 -lt int2    int1小于int2为真

int1 -le int2    int1小于等于int2为真

= 等于 如:if [ “$a” = “$b” ]

== 等于 如:if [ “$a” == “$b”],与=等价

!= 不等于 如:if [ "$a" != "$b" ]

20.2.3 文件的判断

-r file     用户可读为真

-w file     用户可写为真

-x file     用户可执行为真

-f file     文件为正规文件为真

-d file     文件为目录为真

-c file     文件为字符特殊文件为真

-b file     文件为块特殊文件为真

-s file     文件大小非0时为真

-t file     当文件描述符(默认为1)指定的设备为终端时为真

20.2.4 复杂与逻辑判断

-a         与

-o        或

!        非

20.3 IF判断符

20.3.1 两个整数数值判断

20.3.1.1 判断两个数值想等

# vi ifTest.sh

#bin/sh

a=10

b=10

if [ $a = $b ];then

echo "a = b"

else

echo "a != b"

fi

# sh ifTest.sh

a = b

20.3.1.2 判断两个数值不相等

# vi ifTest.sh

#bin/sh

a=10

b=9

if [ $a != $b ];then

echo "a != b"

else

echo "a = b"

fi

$ sh ifTest.sh

a != b

20.3.1.3 判断两值的大小

# vi ifTest.sh

#bin/sh

a=10

b=9

if [ $a -gt $b ];then

echo " a > b"

else

echo "a < b"

fi

$ sh ifTest.sh

a > b

20.3.1.4 多层判断

$ vi ifTest.sh

#bin/sh

a=8

b=9

c=7

if [ $a -gt $b ];then

echo " a > b"

elif [ $a -gt $c ];then

echo "a > c"

else

echo " a !> b and a !> c"

fi

$ sh ifTest.sh

a > c

20.3.1.5 判断是否为空

实例一

# vi ifz.sh

#bin/sh

a=

if [ -z $a ];then

echo "a is null"

fi

# sh ifz.sh

a is null

实例二

# vi ifn.sh

#bin/sh

a=a

if [ -n $a ];then

echo "a is not null"

fi

$ sh ifTest.sh

d is not null

20.3.2 内循环的IF

$ sh insideSh.sh

#!/bin/bash

a=100

if [ $a -ge 60 ];then

if [ $a -ge 80 ];then

if [ $a -gt 90 ];then

echo " a > 90 "

else

echo "a > 80"

fi

else

echo "a > 60"

fi

else

echo " a < 60"

fi

$ sh insideSh.sh

a > 90

20.4 FOR循环符

20.4.1 FOR循环使用

20.4.1.1 随机生成数

$ sh forNumber.sh

#!bin/sh

for i in {1..100};do

echo $i

done

$ sh forNumber.sh

1

2

3

4

5

*************

或者写成以下的格式

#!bin/sh

for i in $(seq 1 10);do

echo $i

done

$ sh forNumber.sh

1

2

3

4

5

*****

20.4.1.2 对一个数进行求和

$ vi forsum.sh

#!bin/base

for((i=1;i<=100;i++));do

sum=$(($sum+$i));

done

echo " 1 .. 100 sum is:"$sum

$ sh forsum.sh

1 .. 100 sum is:5050

20.4.1.3 九九乘法表

$ vi fornine.sh

#!/bin/bash

for((i=1;i<=9;++i))

do

for((j=1;j<=i;j++))

do

echo -ne "$i*$j=$((i*j))\t"

done

echo

done

$ sh fornine.sh

1*1=1

2*1=2 2*2=4

3*1=3 3*2=6 3*3=9

4*1=4 4*2=8 4*3=12 4*4=16

5*1=5 5*2=10 5*3=15 5*4=20 5*5=25

6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36

7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49

8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64

9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

20.4.1.4 求100以内的素数

$ vi forprime.sh

for ((i=2;i<=100;i++));do

for ((x=2;x<=i;x++));do

if [ $[$i%$x] -eq 0 ];then

break;

fi

done

if [ $i -eq $x ];then

echo "$i is 质数"

fi

done

$ sh forprime.sh

2 is 质数

3 is 质数

5 is 质数

7 is 质数

11 is 质数

13 is 质数

*******

20.4.1.5 遍历文件的内容

$ vi forTest.sh

#!bin/base

hosts=`cat /etc/hosts`

for i in $hosts

do

echo $i

done

或写成

for readFile in `cat $1`;

do

echo $readFile

done

20.4.2 批量替换文件的后缀

20.4.2.1 脚本实例

# touch 123.jpg 1234.jpg

# vim replaceSuffix.sh

#!bin/bash

for obj in $(ls *.jpg)

do

mv ${obj} $(echo ${obj/%jpg/JPG})

done

20.4.2.2 脚本运行

# ls

1234.JPG 123.JPG replaceSuffix.sh

20.4.3 列出文件夹下的所有文件

实现脚本

# cat ll-file.sh

#!bin/bash

for file in `ls`

do

echo $file

done

运营效果

# sh ll-file.sh

1.txt

get-dir.sh

ll-file.sh

xiaoxu.sh

20.5 WHILE 循环符

20.5.1 while 循环符的使用

20.5.1.1 依次循环查找出最大的数

$ vi whiletest.sh

#!bin/base

min=1

max=5

while [ $min -le $max ]

do

echo $min

min=`expr $min + 1`

done

$ sh whiletest.sh

1

2

3

4

5

20.5.1.2 求能4整除的数

$ vi whileEven.sh

#!bin/sh

i=1

while(($i<100))

do

if(($i%4==0))

then echo $i

fi

i=$(($i+1))

done

$ sh whileEven.sh

4

8

12

16

20

24

20.5.2 WHILE快速循环

# while true; do ll -h; sleep 4s; done;

$ while true;

> do

> ll -h

> sleep 2s

> done;

20.6 CASE 多重分支

20.6.1 执行多个命令

20.6.1.1 按照条件执行命令

$ sh casetest.sh

#!/bin/bash

echo

echo "Command action"

echo -e "\th\t显示命令帮助"

echo -e "\tf\t显示磁盘分区"

echo -e "\td\t显示磁盘挂载"

echo -e "\tm\t查看内存使用"

echo -e "\tu\t查看系统负载"

echo -e "\tq\t退出程序"

echo

#echo -ne "Command (h for help): "

#read command

read -p "Command (h for help): " command

case "$command" in

h)

echo "Command action"

echo -e "\th\t显示命令帮助"

echo -e "\tf\t显示磁盘分区"

echo -e "\td\t显示磁盘挂载"

echo -e "\tm\t查看内存使用"

echo -e "\tu\t查看系统负载"

echo -e "\tq\t退出程序"

echo

;;

f)

fdisk -ul

;;

d)

df -Th

;;

m)

free -m

;;

u)

uptime

;;

q)

exit

;;

'')

echo "Command (h for help): "

;;

*)

echo "$command: unknown command"

Esac

$ sh casetest.sh

Command action

h 显示命令帮助

f 显示磁盘分区

d 显示磁盘挂载

m 查看内存使用

u 查看系统负载

q 退出程序

Command (h for help):

20.6.1.2 实现正则匹配CASE

$ sh whilecase.sh

#!/bin/bash

#实现输入成绩等级判断

while :

do

read -p "请输入一个成绩[0-100],按"q"退出: " grade

case "$grade" in

[1-5][0-9])

echo "差"

;;

[6-7][0-9])

echo "良"

;;

[8-9][0-9]|100)

echo "优"

;;

q)

exit

;;

*)

echo "你输入的不正确,请重新输入"

esac

done

| 是或的意思

$ sh whilecase.sh

请输入一个成绩[0-100],按q退出: 40

请输入一个成绩[0-100],按q退出: 90

请输入一个成绩[0-100],按q退出: 129

你输入的不正确,请重新输入

请输入一个成绩[0-100],按q退出: 32

请输入一个成绩[0-100],按q退出:

20.7 函数编程

20.7.1 参数函数

# vi function.sh

#!/bin/bash

function hello_world(){

echo "function test"

echo $1 $2

return 1

}

hello(){

echo "helloword"

}

# 在此处调用

hello_world ede ssd

hello

# 在此处进行测试

# sh function.sh

function test

ede ssd

helloword

20.8 常见文件编程

20.1 获取文件命与后缀

20.1.1 脚本实例

# cat xiaoxu.test

#!bin/bash

fileName='1234.txt'

# 获取文件的名字

echo ${fileName%.*}

#获取文件的后缀

echo ${fileName##*.}

20.1.2 脚本效果

# sh xiaoxu.sh

1234

txt

20.2 字符串替换

20.2.1 脚本实例

# vim replaceShell.sh

#!bin/base

str='Hello World'

# 替换开头。如果STR以OLD串开头,则替换

# ${STR/#$OLD/$NEW}

# 替换结尾。如果STR以OLD串结尾,则替换。

# ${STR/%$OLD/$NEW}

# 替换第一个匹配的字母

echo ${str/o/O}

# 全部匹配替换

echo ${str//o/O}

# 开始从后面开始匹配

echo ${str/%ld/ID}

20.2.2 运行效果

# sh replaceShell.sh

HellO World

HellO WOrld

Hello WorID

20.3 字符串删除

20.3.1 脚本实例

# vim deleteShell.sh

#!bin/base

str='Hello World'

# 删除第一个匹配的单词

echo ${str#He}

# 正则删除单词

echo ${str#He*o}

# 正则匹配多个值

echo ${str##He*o}

20.3.2 运行效果

# sh deleteShell.sh

llo World

World

Rld

20.4 字符串操作

20.4.1 脚本实例

# vim replaceSuffix.sh

#!bin/bash

str='123456789abcdEFGH'

# 获取字符串的长度

echo ${#str}

# 截取字符串

echo ${str:1:3}

# 把小写字母转大写

echo $str|sed 's/.*/\U&/'

# 把大写字母转小写

echo $str|sed 's/.*/\L&/'

#获取制定分隔符的位置

echo ${str##*:}

# 获取第一个分割的位置

echo ${str%%:*}

# 打印最后5个字符

echo ${str: -4}

# 输出该变量的值

echo ${str:-5}

说明: \U 是转换为大写,\L 是转换为小写

20.4.2 运行效果

# sh replaceSuffix.sh

17

234

123456789ABCDEFGH

123456789abcdefgh

20.5 字符串的空格替换

20.5.1 脚本实例

# cat 123.txt

1233 342 242 2323231

131313 2331

20.5.2 运行效果

# sed 's/[[:space:]]//g' 123.txt

12333422422323231

1313132331

20.5.3 替换成一行

# sed 's/[[:space:]]//g' 123.txt |sed ":a;N;s/\n//g;ta"

123334224223232311313132331

参考资料:

http://kodango.com/sed-and-awk-notes-part-4

http://kodango.com/sed-and-awk-notes-part-5

20.9 脚本调试

sh 调试

# sh -x xiaoxu.sh

+ str='ssss

csdd

scscee

def'

+ echo ssss csdd scscee def

+ awk '{if ($1 == "ssss"){print $2 $3}}'

Csddscscee

带+ 号的是脚本中的执行过程

21 工作中常用知识汇总

21.1 替换文件中的隐藏字符

# cat asciiReplaceScript.sh

#!bin/sh

# 特殊字符查看表

# https://blog.csdn.net/xfg0218/article/details/80901752

echo "参数说明"

echo -e "\t 把此脚本复制到带有特殊字符的文件夹下运行此脚本即可把全部文件进行替换,例如:sh asciiReplaceScript.sh"

echo

echo -e "\t 转换开始...... \n "

# 设置脚本开始时间

starttime=`date +'%Y-%m-%d %H:%M:%S'`

# 特殊字符的集合,28是特殊字符的10进制代码

soh=`echo 1 | awk '{printf("%c", $1)}'`

stx=`echo 2 | awk '{printf("%c", $1)}'`

etx=`echo 3 | awk '{printf("%c", $1)}'`

eot=`echo 4 | awk '{printf("%c", $1)}'`

enq=`echo 5 | awk '{printf("%c", $1)}'`

ack=`echo 6 | awk '{printf("%c", $1)}'`

bel=`echo 7 | awk '{printf("%c", $1)}'`

bs=`echo 8 | awk '{printf("%c", $1)}'`

ht=`echo 9 | awk '{printf("%c", $1)}'`

lf=`echo 10 | awk '{printf("%c", $1)}'`

vt=`echo 11 | awk '{printf("%c", $1)}'`

ff=`echo 12 | awk '{printf("%c", $1)}'`

cr=`echo 13 | awk '{printf("%c", $1)}'`

so=`echo 14 | awk '{printf("%c", $1)}'`

si=`echo 15 | awk '{printf("%c", $1)}'`

dle=`echo 16 | awk '{printf("%c", $1)}'`

dc1=`echo 17 | awk '{printf("%c", $1)}'`

dc2=`echo 18 | awk '{printf("%c", $1)}'`

dc3=`echo 19 | awk '{printf("%c", $1)}'`

dc4=`echo 20 | awk '{printf("%c", $1)}'`

nak=`echo 21 | awk '{printf("%c", $1)}'`

syn=`echo 22 | awk '{printf("%c", $1)}'`

etb=`echo 23 | awk '{printf("%c", $1)}'`

can=`echo 24 | awk '{printf("%c", $1)}'`

em=`echo 25 | awk '{printf("%c", $1)}'`

sub=`echo 26 | awk '{printf("%c", $1)}'`

esc=`echo 27 | awk '{printf("%c", $1)}'`

fs=`echo 28 | awk '{printf("%c", $1)}'`

gs=`echo 29 | awk '{printf("%c", $1)}'`

rs=`echo 30 | awk '{printf("%c", $1)}'`

us=`echo 31 | awk '{printf("%c", $1)}'`

del=`echo 127 | awk '{printf("%c", $1)}'`

# 循环把文件下的所有文件取出来

for replaceFile in `ls *`

do

# 去除此脚本文件

if [ $replaceFile = $0 ];then

continue;

fi

echo -e "\t 文件" $replaceFile "替换开始...."

# 单个文件处理的额开始时间

single_time=`date +'%Y-%m-%d %H:%M:%S'`

# 单个文件替换开始

sed -i -e 's/[\x0]//g' -e 's/'$soh'//g' -e 's/'$stx'//g' -e 's/'$etx'//g' -e 's/'$eot'//g' -e 's/'$enq'//g' -e 's/'$ack'//g' -e 's/'$bel'//g' -e 's/'$bs'//g' -e 's/'$lf'//g' -e 's/'$vt'//g' -e 's/'$ff'//g' -e 's/'$cr'//g' -e 's/'$so'//g' -e 's/'$si'//g' -e 's/'$dle'//g' -e 's/'$dc1'//g' -e 's/'$dc2'//g' -e 's/'$dc3'//g' -e 's/'$dc4'//g' -e 's/'$nak'//g' -e 's/'$syn'//g' -e 's/'$etb'//g' -e 's/'$can'//g' -e 's/'$em'//g' -e 's/'$sub'//g' -e 's/'$esc'//g' -e 's/'$fs'//g' -e 's/'$gs'//g' -e 's/'$rs'//g' -e 's/'$us'//g' -e 's/'$del'//g' -e 's/'$'//g' $replaceFile

# 就算单个文件耗时

single_endtime=`date +'%Y-%m-%d %H:%M:%S'`

single_start_seconds=$(date --date="$single_time" +%s);

single_end_seconds=$(date --date="$single_endtime" +%s);

echo -e "\t 文件" $replaceFile "替换结束,耗时:"$((single_end_seconds-single_start_seconds))"s"

echo -e "\n"

done

echo -e "\t 全部文件转换结束......"

# 全部文件替换的总耗时

endtime=`date +'%Y-%m-%d %H:%M:%S'`

start_seconds=$(date --date="$starttime" +%s);

end_seconds=$(date --date="$endtime" +%s);

echo -e "\t 脚本总耗时:"$((end_seconds-start_seconds))"s"

# 退出脚本

exit

21.2 获取本脚本所在的路径

21.2.1 执行的脚本

# cat get-dir.sh

#!bin/bash

bashPath=$(cd `dirname $0`;pwd)

echo $bashPath

# cat get-dir.sh

#!bin/bash

dirbash=$(eval pwd)

echo $dirbash

# cat get-dir.sh

#!bin/bash

bashpath=`pwd`

echo $bashpath

# sh get-dir.sh

/home/xiaoxu/test

21.2.2 运行效果

# sh baseShellPath.sh

/home/xiaoxu/test

21.3 批量改变文件的后缀

# cat batch-change-suffix.sh

#!bin/bash

oldsuffix="jpeg"

newsuffix="jpg"

dir=$(eval pwd)

for file in $(ls $dir | grep .${oldsuffix})

do

name=$(ls ${file} | cut -d. -f1)

mv $file ${name}.${newsuffix}

done

echo "change $oldsuffix to $newsuffix successd!"

或使用以下方法

for i in `ls *.txt`; do sed 's/|$//' $i > ${i/csv/txt} ;done

21.4 批量替换文本中的字符

# cat replace-middle-char.sh

#!bin/bash

for file in `ls | grep .jpg`

do

newfile=`echo $file | sed 's/-//g'`

mv $file $newfile

done

21.5 Linux常见的特殊字符问题

21.5.1 \x01 字符

\x01\x015138223017959\x01G\x015419\x012006-06-14 00:00:00.0\x012999-12-31 00:00:00.0

说明:这是hive的默认分隔符,用脚本awk或python可以把分隔符设置为'\x01',在vim中可以使用sed -i -e 's/\\x01//g' fileName 来替换掉

22 Linux 正则的使用

22.1 正则说明

22.1.1 Grep 常用正则使用

^ 行首

$ 行尾

. 除了换行符以外的任意单个字符

* 匹配零次多多次

.* 所有字符

| : 表示或的范围

+ 一次或多次匹配

? 零次或者一次匹配

[] 字符组内的任一字符

[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)

^[^] 非字符组内的字符开头的行

[a-z] 小写字母

[A-Z] 大写字母

[a-Z] 小写和大写字母

[0-9] : 匹配0-9数字的的范围的数据

[^0-9] : 匹配不在0-9数字的的范围的数据

[a-zA-Z] : 匹配小写字母与大写字母

[0-9a-zA-Z] : 匹配数字与小写字母与大写字母的匹配

[a-z][A-Z]:匹配第一个字母是小写字母第二个字母是大写字母的数据

[0-9][0-9]:匹配第一个数字与第二个数字数据

\b[0-9][0-9]\b : 匹配有两位数字的数据

x\{m,n\} :重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。

m.*c : *表示匹配任何长度的字符串,例如:mnrnrvnfdc,mfrf3434c

m..c : 表示m与c之间只有两个字母相隔的匹配,例如:mdfc,m65c

[.:/] : 匹配数据中的.:/

^root : 首字母是root的匹配,注意与[^root]的区别

root$ : 尾字符是root的匹配

^$ : 表示当前的空行

\w : 与[a-zA-Z0-9]匹配相等,匹配任何字类字符

\W : 与[^a-zA-Z0-9]匹配相等,匹配任何非字类字符

\b : 代表单词的分割,例如:[\bx\b] 表示匹配***x***

[[:alnum:]] 相当于[a-zA-Z0-9]

[[:blank:]] 匹配范围为 空格和TAB键

22.1.2 Grep 常用实例

22.1.2.1 查看样例

# cat 1.txt

1212,1213,23

3d,sfsd

DDFEG:dfd:/24343

多的地方8089,9080

地方:2323:电放费

6565/212/867868

分 /想 晚上

哥/菲:问我

1234566 990

22.1.2.2 匹配含有0-9的数据

# grep '[0-9]' 1.txt

1212,1213,23

3d,sfsd

DDFEG:dfd:/24343

多的地方8089,9080

地方:2323:电放费

6565/212/867868

1244566 990

22.1.2.3 匹配含有a-z到A-Z的数据

# grep '[a-zA-Z]' 1.txt

3d,sfsd

DDFEG:dfd:/24343

22.1.2.4 不匹配含有a-zA-Z的数据

# grep '[^a-zA-Z]' 1.txt

1212,1213,23

3d,sfsd

DDFEG:dfd:/24343

多的地方8089,9080

地方:2323:电放费

6565/212/867868

分 /想 晚上

哥/菲:问我

1234566 990

22.1.2.5 匹配数据中的空行

# grep -n '^$' 1.txt

6:

22.1.2.6 匹配TAB行

# grep -n '[[:blank:]]' 1.txt

8: 分 /想 晚上

10:123 4566 990

22.1.2.7 表示或的匹配

# grep -n 'sbin/\(bash\|nologin\)' passwd

2:bin:x:1:1:bin:/bin:/sbin/nologin

3:daemon:x:2:2:daemon:/sbin:/sbin/nologin

4:daemon:x:2:2:daemon:/sbin:/sbin/bash

**********

22.1.2.8 匹配制定范围的数字

# grep '^[0-9]\{4,10\}$' 1.txt

2323234

4565754323

45434

22.1.2.9 匹配15到18位的身份证号(尾号有X)

# grep '^[1-9]\([0-9]\{13\}\|[0-9]\{16\}\)[0-9xX]$' 1.txt

576786543232435456

45474634534257465X

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏禁心尽力

多线程编程:阻塞、并发队列的使用总结

最近,一直在跟设计的任务调度模块周旋,目前终于完成了第一阶段的调试。今天,我想借助博客园平台把最近在设计过程中,使用队列和集合的一些基础知识给大家总结一下,方便...

26250
来自专栏程序员宝库

【译】深入研究 Laravel 的依赖注入容器

原文地址:Laravel's Dependency Injection Container in Depth 下面是中文翻译。 Laravel拥有强大的控制反转...

62770
来自专栏大闲人柴毛毛

三分钟理解“中介者模式”——设计模式轻松掌握

中介者模式的官方定义: 中介者模式使用一个中介对象来封装一系列对象的交互,从而使各对象不需要显式的相互引用,从而使得对象我们耦合松散,而且可以独立地改变对象之间...

392110
来自专栏用户2442861的专栏

python操作redis简单例子

#2、配置  配置一下吧,默认配置文件在: “/etc/redis/redis.conf”  绑定ip:  “bind 127.0.0.1″ -> “b...

27520
来自专栏互扯程序

java中的内存模型

现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。

17940
来自专栏牛肉圆粉不加葱

JVM GC 那些事(一)- JVM 运行时内存划分

对于经常使用 Spark 的人来说,如何设置 driver 或 executor 的内存大小,如何尽量减少 GC 相信不会陌生。要做好这两点,除了 Spark ...

5310
来自专栏Linux驱动

第1阶段——关于u-boot目标文件start.o中.globl 和.balignl理解(3)

汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为伪操作. .globl _start 作用:声明一个_sta...

18350
来自专栏vue

C++项目中采用CLR的方式调用C#编写的dll

1、注意事项:在编写C#DLL类库时,最好不要出现相同的命名空间,否则在C++中调用可能会出现编译错误。 2、将C#的源码生成的“dll”文件复制到C++项目中...

31730
来自专栏张戈的专栏

Linux:sed命令详解

1. 简介 sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。 ? sed 编辑器逐...

51460
来自专栏代码GG之家

android MVVM开发模式(三)

android MVVM开发模式(三) 为了更好地理解@BindingAdapter,github地址里面提交了一个adapters目录,将系统提供的适配提交上...

20450

扫码关注云+社区

领取腾讯云代金券