awk
入力区切り文字(-F、FS)、出力区切り文字(OFS)
awk でシェル変数を参照する
一. awk とシェル変数の交換の問題#
awk とシェル変数の交換の問題
1、-v オプションを使用する
2、ダブルクォーテーションを使用するが、awk 内部の $0 $1 などの $ 記号の前に \ でエスケープする必要がある
3、シングルクォーテーションを使用し、変数を囲み、その前に $ 記号を付けて再度変数の値を参照する。これは 2 回値を取得することに相当する
#例:-vオプションを使用する
[root@cPen_A ~]# sg="panjinhao"
[root@cPen_A ~]# echo $sg
panjinhao
[root@cPen_A ~]# echo|awk '{print $sg}'
[root@cPen_A ~]# echo|awk -v bsg=$sg '{print bsg}'
panjinhao
[root@cPen_A ~]# ls|awk -v bsg=$sg '{print bsg}'
panjinhao #注:lsは複数行出力する
panjinhao
……
panjinhao
[root@cPen_A lianxi]# vim test2.sh
awk -v var=$1 -F: '$1==var{print NR,$0}' /etc/passwd
[root@cPen_A lianxi]# bash test2.sh root
1 root:x:0:0:root:/root:/bin/bash
[root@cPen_A lianxi]# bash test2.sh sanchuang
21 sanchuang:x:1000:1000::/home/sanchuang:/bin/bash
#注:第1の$1は位置変数、第2の$1は第1のフィールド
#例:ダブルクォーテーションを使用するが、awk内部の$0 $1などの$記号の前に\でエスケープする必要がある
[root@cPen_A lianxi]# mv="zhangjie"
[root@cPen_A lianxi]# useradd zhangjie_123
[root@cPen_A lianxi]# cat /etc/passwd|awk -F: "/^$mv/{print \$1,\$3}"
zhangjie_123 12358
#例:シングルクォーテーションを使用し、変数を囲み、その前に$記号を付けて再度変数の値を参照する。これは2回値を取得することに相当する
[root@cPen_A lianxi]# sg=3
[root@cPen_A lianxi]# awk -F: '/root/{print $1,$'$sg'}' /etc/passwd
root 0
operator 11
二。プロセス間通信の方法#
1、共有メモリ
2、セマフォ
3、シグナル
4、パイプ
5、キュー
6、ソケット
[root@cPen_A lianxi]# cat /etc/shadow
第2のフィールド:パスワードフィールド
*オペレーティングシステムに付属している、パスワードなし
!!ユーザーが作成した、パスワードなし
ヒント:パスワードフィールドが*、!!はパスワードが設定されていないことを示す;パスワードフィールドが空であることは、パスワードがクリアされたことを示す。
#例:パスワードが設定されていないユーザー
[root@cPen_A lianxi]# cat /etc/shadow|awk -F: 'BEGIN{i=0}length($2)<=2{print $1,"はパスワードが設定されていない";i++}END{print "合計で"i"人のユーザーがいる"}'
三. awk の組み込み関数#
awk の組み込み関数:
length()
int()
sqrt()
system()
文字列関数
sub()
index()
length()
split()
数値関数
yum install python3 python3 をインストールする
#例:0-1の間のランダム数を生成する
[root@cPen_A lianxi]# echo |awk '{print rand()}'
0.237788
#例:0-100の間のランダム数を生成する
[root@cPen_A lianxi]# echo |awk '{print rand()*100}'
23.7788
[root@cPen_A lianxi]# echo |awk '{print int(rand()*100)}'
23
四。フロー制御#
フロー制御:プロセス制御 control flow
for
while
case
if
if文
単一分岐
[root@cPen_A lianxi]# awk -F: '{if($1 ~ /\<...\>/)print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
[root@cPen_A lianxi]# awk -F: '$1 ~ /\<.{3}\>/{print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
二重分岐
[root@cPen_A lianxi]# awk -F: '{if($1 ~ /\<...\>/)print $0;else print "条件を満たしていない"}' /etc/passwd
条件を満たしていない
bin:x:1:1:bin:/bin:/sbin/nologin
#練習
/etc/passwd
$3はuid ユーザーの番号
もしユーザーの番号が0 --> 管理者
1~999 --> プログラムユーザー
1000より大きい --> 一般ユーザー
最後に、管理者、プログラムユーザー、一般ユーザーがそれぞれ何人いるかを統計する。
-----------------------------------------------------
[root@cPen_A ~]# awk -F: 'BEGIN{x=0;y=0;z=0}{if($3=="0") {print $1,"管理者";x++} else if($3>=1 && $3<=999) {print $1,"プログラムユーザー";y++} else {print $1,"一般ユーザー";z++}}END{print "管理者"x,"プログラムユーザー"y,"一般ユーザー"z}' /etc/passwd
root 管理者
bin プログラムユーザー
……
管理者1 プログラムユーザー25 一般ユーザー40
五. awk の for ループ、配列#
awk の難点:
-
正規表現
-
if
-
組み込み関数
-
組み込み変数
-
for、配列 array
六. sed#
sed とは?what --> テキストストリームエディタ
何に使うのか?where how --> テキストの変更と置換 --> modify and substitute
sed は正規表現をサポートする非対話型ストリーム編集ツール(stream editor)
スクリプト内でテキストを変更またはテキストを置換するための最良のツール
対話型:一問一答。例えば python3 でコマンドを入力する
2 つのスペース
パターンスペース --> データを処理する場所 --> 1 行のデータを処理した後、パターンスペースはクリアされる
ホールドスペース --> データを一時的に保存する場所
パターンスペースをホールドスペースに移すコマンド:h、H
ホールドスペースをパターンスペースに移すコマンド:g、G
#注:パフォーマンス意識、sed はメモリ内で実行され、ディスクよりも速い
#注:容量意識
#例:-iオプション ファイル内で直接変更し、画面には出力しない
[root@cPen_A lianxi]# sed -i 's/xiaomi/redmi/g' test.txt
#例:パイプで渡す
[root@cPen_A lianxi]# cat chen |sed 's/xiaomi/redmi/g'
[root@cPen_A lianxi]# cat -n /etc/passwd|head |tail -6
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
#例:-nオプション 一致した行を表示する(そうでなければすべて出力される)
[root@cPen_A lianxi]# cat -n /etc/passwd|sed -n '5,10p'
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
sed の p コマンドの例#
= :行番号を出力する
pコマンド出力時:
連続した行
[root@localhost lianxi]# cat /etc/passwd|sed -n '1,5p'
不連続な行
[root@localhost lianxi]# cat /etc/passwd|sed -n '10p;20p'
例:sedのpコマンドの例
sed -n ‘行番号1,行番号2p’ 出力ファイル
[root@localhost lianxi]# cat /etc/passwd|sed -n '1,5p' #注:連続して,で区切る
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost lianxi]# cat /etc/passwd|sed -n '=;1,5p' #注:=;行番号を出力する
1
root:x:0:0:root:/root:/bin/bash
2
bin:x:1:1:bin:/bin:/sbin/nologin
3
daemon:x:2:2:daemon:/sbin:/sbin/nologin
4
adm:x:3:4:adm:/var/adm:/sbin/nologin
5
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6
7
……
14
[root@localhost lianxi]# cat -n /etc/passwd|sed -n '1,$p' #注:$p最後の行
[root@localhost lianxi]# cat -n /etc/passwd|sed -n '5,+5p' #注:第5行から5行追加
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost lianxi]# cat -n /etc/passwd|sed -n '5,100!p' #注:反転、1から4行を取得
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
#例:ステップ値
# cat -n /etc/passwd|sed -n '1~2p'
# cat -n /etc/passwd|sed -n '2~2p'
[root@localhost lianxi]# cat -n /etc/passwd|sed -n '1~2p' #注:奇数行、1から始めて2行ごとに
1 root:x:0:0:root:/root:/bin/bash
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
19 chrony:x:998:996::/var/lib/chrony:/sbin/nologin
21 chenpeng:x:1001:1001::/home/chenpeng:/bin/bash
23 nginx:x:996:994:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost lianxi]# cat -n /etc/passwd|sed -n '2~2p' #注:偶数行
2 bin:x:1:1:bin:/bin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
8 halt:x:7:0:halt:/sbin:/sbin/halt
10 operator:x:11:0:operator:/root:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
20 mysql:x:1000:1000::/home/mysql:/sbin/nologin
22 redis:x:997:995:Redis Database Server:/var/lib/redis:/sbin/nologin
#例:シェル変数をsedに渡す
#ダブルクォーテーション 推奨
[root@localhost lianxi]# num1=6
[root@localhost lianxi]# num2=10
[root@localhost lianxi]# cat -n /etc/passwd|sed -n "${num1},${num2}p"
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
#シングルクォーテーション
[root@localhost lianxi]# cat -n /etc/passwd|sed -n ''${num1},${num2}'p'
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
----------------------------------------------------------
#例:bashを含む行を表示する
[root@localhost lianxi]# cat /etc/passwd|sed -n '/bash/p'
root:x:0:0:root:/root:/bin/bash
chenpeng:x:1001:1001::/home/chenpeng:/bin/bash
[root@localhost lianxi]# cat /etc/passwd|egrep "bash"
root:x:0:0:root:/root:/bin/bash
chenpeng:x:1001:1001::/home/chenpeng:/bin/bash
[root@localhost lianxi]# cat /etc/passwd|awk '/bash/'
root:x:0:0:root:/root:/bin/bash
chenpeng:x:1001:1001::/home/chenpeng:/bin/bash
#例:#で始まる行を出力する
[root@localhost lianxi]# cat /etc/ssh/ssh_config |sed -n '/^#/p'
#例:#で始まらない行を出力する
[root@localhost lianxi]# cat /etc/ssh/ssh_config |sed -n '/^#/!p'
#例:#と!で始まらない行を表示する
[root@localhost lianxi]# cat /etc/ssh/ssh_config |sed -r -n '/^#|^$/!p' #注:-rはより多くの正規表現をサポート
[root@localhost lianxi]# cat /etc/ssh/ssh_config |egrep -v '^#|^$'
#例:/で終わる行を表示する
[root@localhost lianxi]# df -h|egrep "/$"
/dev/mapper/centos-root 17G 9.9G 7.2G 58% /
[root@localhost lianxi]# df -h|sed -n '/\/$/p'
/dev/mapper/centos-root 17G 9.9G 7.2G 58% /
#例:a-Zで始まる行
[root@localhost lianxi]# cat /etc/passwd|sed -n '/^[a-Z]/p'
#例:a-Zで始まらない行
[root@localhost lianxi]# cat /etc/passwd|sed -n '/^[^a-Z]/p'
問題:nginxのaccess.logファイルから3月18日15:30:00 -- 16:48:10の時間帯内のすべてのアクセスログを切り取る
[root@cPen_A lianxi]# service firewalld stop #注:firewalldサービスを即座に停止する
[root@cPen_A lianxi]# systemctl disable firewalld #注:firewalldサービスを次回起動時に開始しないように設定する-->次回マシンを再起動する際に起動しない
[root@cPen_A nginx]# tail -f access.log #注:最後の行を動的に監視する
192.168.0.17 - - [09/Jan/2021:16:36:03 +0800] "GET /favicon.ico HTTP/1.1" 404 3650 "http://192.168.0.118/" "Mozilla/5.0 (Linux; Android 10; PCT-AL10; HMSCore 5.1.0.300; GMSCore 20.26.14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 HuaweiBrowser/11.0.5.304 Mobile Safari/537.36" "-"
[root@cPen_A nginx]# pwd
/var/log/nginx #注:nginxのログファイルのパス
[root@cPen_A nginx]# ls
access.log access.log-20201202.gz error.log error.log-20201202.gz
#注:access.logはnginxのアクセスログファイルで、訪問したウェブサイトの情報を記録している
[root@cPen_A nginx]# cat access.log | awk -F'[()]' '{print $2}'|sort|uniq -c|sort -nr
13 Windows NT 10.0; WOW64 #注:ソートして重複を削除し、降順にソートして数量を表示
4 Linux; Android 10; PCT-AL10; HMSCore 5.1.0.300; GMSCore 20.26.14
---------------------------------------------------------------------------
[09/Jan/2021:16:32:46 +0800] --> 09/Jan/2021:16:32:46
[09/Jan/2021:16:33:07 +0800] --> 09/Jan/2021:16:32:46
#例:その時間帯のすべてのアクセスログを検索する
[root@cPen_A nginx]# cat access.log|sed -n '/09\/Jan\/2021:16:32:46/,/09\/Jan\/2021:16:33:07/p'
#例:正規表現の書き方
[root@cPen_A nginx]# cat access.log|sed -r -n '/09\/Jan\/2021:16:(3[789]|4[0-9]|5[01]):(0[1-9]|[1-5][0-9])/p'
#注:分の範囲は37~51 秒の範囲は01~59
#37~51
#37~39
#40~49
#50~51
#01~59
0[1-9]|[1-5][0-9]
sed の d コマンドの例#
sedのdコマンドの例
削除操作は行番号と一致パターンに基づいて行うことができる
#例:denghuiを含む行を削除する
[root@cPen_A nginx]# cat /etc/passwd|sed '/denghui/d'
#例:-iオプションで元のファイルを直接変更し、redmiを含む行を削除する
[root@cPen_A lianxi]# sed -i '/redmi/d' test.txt
#例:行に基づいて削除する
[root@cPen_A lianxi]# sed -i '2d' test.txt #注:第2行を削除する
sedの検索方法:
1、行番号に基づいて
2、一致パターンに基づいて --> 正規表現=文字+特殊記号
3、文字列に基づいて
#例:第4行の後にhuaweiを追加する
[root@cPen_A lianxi]# sed -i '4a huawei' test.txt
#例:第4行の前にappleを挿入する
[root@cPen_A lianxi]# sed -i '4i apple' test.txt
#例:VIVOの行の前にOPPOを挿入する
[root@cPen_A lianxi]# sed -i '/VIVO/i OPPO' test.txt
#例:VIVOの行の後にAPPLEを追加する。&は前のすべてを示す
[root@cPen_A lianxi]# sed -i 's/VIVO/& APPLE/' test.txt
#例:すべてのhuaweiをsanchuangに置き換える
[root@cPen_A lianxi]# sed -i 's/huawei/sanchuang/g' test.txt
sedのコマンド:
p
d
a
i
s
c
r
w