作者:小徐
製作時間:20180601
聯繫方式:[email protected]
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