當(dāng)前位置:首頁 > IT技術(shù) > 系統(tǒng)服務(wù) > 正文

【Shell】shell 日志處理(一行一行讀文本-必須用while不能用for)shell 腳本 遍歷文件 找出包含特定字符串的行數(shù)/行
2021-09-28 17:01:50

目錄

??shell 獲取結(jié)果中的第n列,第n行??

??AWK輸出某幾列??

??awk??遍歷文件行處理??

??shell 腳本 遍歷文件 找出包含特定字符串的行數(shù)/行??



??shell 獲取結(jié)果中的第n列,第n行??

ls -l | awk '{print $5}' | sed -n '2p'

awk 是很實用的文本處理命令,print 到后帶的是你要獲取第幾列,sed -n 是指定第幾行。

AWK輸出某幾列

有這樣一個文本,需要截取前5行

[root@SH]# cat test.txt 
2 3651415576 940761 0 0 0000000000000000
3 3532686312 939551 0 0 0000000000000000
4 3873453656 984285 0 0 0000000000000000
5 3884604640 970761 0 0 0000000000000000
6 2116906224 493295 0 0 0000000000000000
7 1760674752 480700 0 0 0000000000000000
8 0 0 29979808 6002 0000000000000000
10 0 0 3299944 1433 0000000000000000
11 0 0 2199434640 312565 0000000000000000

  • 可以awk '{print $1,$2,$3,$4,$5}
  • 另外一種實現(xiàn)方法awk '{NF-=2}1',這里的1換成別的數(shù)字也可以,NF-=2表示倒數(shù)第二列?

linux下統(tǒng)計某個進程的CPU占用和內(nèi)存使用

#!/bin/bash
# while loop

CpuMemStat=""
datemk=""
while true
do
CpuMemStat=` ps aux |grep -i server |grep redis |grep -v py`
datemk=`date "+%Y-%m-%d %H:%M:%S"`
echo $datemk $CpuMemStat >> result.txt
#echo $datemk $CpuMemStat
sleep 20s
done

上面的遇到CpuMemStat結(jié)果是多行的就歇菜了,改成

#!/bin/bash
# while loop
CpuMemStat=""
datemk=""

CpuMemStat=`ps aux |sed -n '1p'|awk '{print $1,$2,$3,$4,$5}'`
datemk=`date "+%Y-%m-%d %H:%M:%S"`
echo $datemk $CpuMemStat >> result.txt

while true
do
#CpuMemStat=` ps aux |grep -i redis-server|awk '{print $1,$2,$3,$4,$5}'`
datemk=`date "+%Y-%m-%d %H:%M:%S"`


ps aux |grep -i redis-server|awk '{print $1,$2,$3,$4,$5}'|while read line
do
echo $line
echo $datemk $line >> result.txt
#echo $datemk $CpuMemStat
done

sleep 1s
done

(一行一行讀,不能用for 必須用while,因為in操作符以任意空白字符作為分割,?而read?line是以回車符作為分割。

注意 | 管道會起子進程,子進程內(nèi)的變量無法傳到外面,例如:

[liuhao@slave04 ~]$ cat test.sh 
#! /bin/sh

x=1
echo "adasd" | while read line
do
x=2
done
echo $x

運行結(jié)果是
[liuhao@slave04 ~]$ sh test.sh
1
原因

原來是因為管道|創(chuàng)建了新的子進程,而子進程是在獨立的進程空間(Context)運行了. 需要跟父進程通信的話, 得使用進程間通信機制. 不是簡單的變量問題。

有一文本文件如下,每行有兩個字符串/空格分開。

$?cat?list.txt?

Gly?G

Ala?A

Val?V

Leu?L

Ile?I

Phe?F



for?line?in?`cat?list.txt`

do

echo?$line

done

得到結(jié)果如下:


Gly

G

Ala

A

Val

V

Leu

L

Ile

I

Phe

F


============

while?read?line

do?

echo?$line

done?list.txt


運行得到結(jié)果如下:


Gly?G

Ala?A

Val?V

Leu?L

Ile?I

Phe?F

awk??遍歷文件行處理

awk基本語法如下:

awk?'BEGIN{//begin code }? ? ? ? ? ? pattern1{//pattern1?code}? ? ? ? ? ? ?pattern2{//pattern2 code}? ? ? ? ? END{//end code }'

BEGIN部分的代碼,最先執(zhí)行

然后循環(huán)從管道中讀取的每行文本,如果匹配pattern1?,則執(zhí)行pattern1 code的代碼,匹配pattern2,則執(zhí)行pattern2 code代碼

最后,執(zhí)行END部分的代碼end code

如下所示,分別求奇數(shù)行與偶數(shù)行的和:

$?seq?1?5

1

2

3

4

5

$?seq?1?5|awk?'BEGIN{print?"odd","even"}? ? NR%2==1{odd+=$0}? ? NR%2==0{even+=$0}? ? END{print?odd,even}'

odd?even

9?6


實戰(zhàn):

info.txt

?-5 ? ? ? ?10.47839 root ssdpool ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
-25 ? ? ? ?10.47839 ? ? rack rack.ssdpool ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
-28 ? ? ? ? 3.49280 ? ? ? ? host rdma61.ssdpool ? ? ? ? ? ? ? ? ? ? ? ??
?18 ? ssd ? 0.87320 ? ? ? ? ? ? osd.18 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?21 ? ssd ? 0.87320 ? ? ? ? ? ? osd.21 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?24 ? ssd ? 0.87320 ? ? ? ? ? ? osd.24 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?28 ? ssd ? 0.87320 ? ? ? ? ? ? osd.28 ? ? ? ? ? ? ?up ?1.00000 1.00000?
-31 ? ? ? ? 3.49280 ? ? ? ? host rdma63.ssdpool ? ? ? ? ? ? ? ? ? ? ? ??
?20 ? ssd ? 0.87320 ? ? ? ? ? ? osd.20 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?22 ? ssd ? 0.87320 ? ? ? ? ? ? osd.22 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?25 ? ssd ? 0.87320 ? ? ? ? ? ? osd.25 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?27 ? ssd ? 0.87320 ? ? ? ? ? ? osd.27 ? ? ? ? ? ? ?up ?1.00000 1.00000?
-34 ? ? ? ? 3.49280 ? ? ? ? host rdma64.ssdpool ? ? ? ? ? ? ? ? ? ? ? ??
?19 ? ssd ? 0.87320 ? ? ? ? ? ? osd.19 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?23 ? ssd ? 0.87320 ? ? ? ? ? ? osd.23 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?26 ? ssd ? 0.87320 ? ? ? ? ? ? osd.26 ? ? ? ? ? ? ?up ?1.00000 1.00000?
?29 ? ssd ? 0.87320 ? ? ? ? ? ? osd.29 ? ? ? ? ? ?down ? ? ? ?0 1.00000?

寫一個shell腳本?run.sh,我給它參數(shù)61(或者63或64),?它就讀取host?rdma61.ssdpool下面的行文字的第一個字段,并逐一輸出log+字段,直至遇到下一個host?rdma?停止。


如:?run.sh?61


輸出:


log18.txt

log21.txt

log24.txt

log28.txt


如:?run.sh?63


log20.txt

log22.txt

log25.txt

log27.txt

腳本

awk -v flag=0 '
/host rdma'$1'/ {flag=1; next}
flag == 1 && /host rdma/ {flage=0; exit}
flag == 1 {print "log"$1".txt"}
' info.txt
?

-v flag=0 # 設(shè)置變量flag=0

/host rdma'$1'/ {flag=1; next}? ? ? ? ? ? ? ? ? ?#匹配到host rdma'$1'執(zhí)行flag=1; next,netx 表示不匹配本文本行后面的內(nèi)容,直接跳到下一行文本

flag == 1 && /host rdma/ {flage=0; exit}? #flag == 1 且匹配到host rdma,則執(zhí)行{flage=0; exit} ,exit 退出結(jié)束

flag == 1 {print "log"$1".txt"}? ? ? ? ? ? ? ? ??#flag == 1 且匹配到host rdma,則執(zhí)行print "log"$1".txt"?

shell 腳本 遍歷文件 找出包含特定字符串的行數(shù)/行

#!/bin/bash

printf "************************************* "
a=0
while read line
do
[[ $line =~ "css" ]] && ((a++))
done < test.txt
echo $a

#!/bin/bash

ceph osd tree |& grep -E "ssd|ssdpool" > osd_nodes_id.txt

strA="rdma63.ssdpool"
while read -r line
do
echo ${line}
if [[ ${line} =~ ${strA} ]];
then
echo "包含"
fi
done < osd_nodes_id.txt

本文摘自 :https://blog.51cto.com/l

開通會員,享受整站包年服務(wù)立即開通 >