mycpen

Mycpen

记录学习历程与受益知识
github
telegram
bilibili

13_Linux基礎-SHELLコマンド-wc-diff-patch-bc-awk

一。振り返り#

sort#

sort

形式:sort オプション ファイル
-n	数値でソート
-r	降順ソート
-k	ソートする列を指定
-t	区切り文字を指定
-u	重複を削除

uniq#

uniq

形式:uniq オプション ファイル
-c	各列の出現回数をカウント
-u	1回だけ出現する行を表示
-d	重複している行のみ表示

cut#

cut

形式:cut オプション 抽出範囲 ファイル
-d	区切り文字を指定
-f	表示する特定のフィールドを指定
-c	特定の文字を指定

テキストの三剣客#

grep フィルタ 一般的な正規表現解析プログラム
grep [オプション]... パターン 対象ファイル
-i	大文字と小文字を区別しない
-v	逆検索、指定した文字を含む行を表示しない
-o	一致した内容を表示し、改行して表示
-n	フィルタリングされた行の行番号を表示
-r	指定したディレクトリ内のすべてのファイルを再帰的に検索(サブディレクトリを含む)
-E	より多くの正規表現拡張をサポート

正規表現#

^aa	aaで始まる行
Aa$	aaで終わる行

ワイルドカード#

*	前の項目に任意の回数マッチ
?	前の項目に0回または1回マッチ
+	前の項目に1回から多回マッチ
.	(プレースホルダー)改行文字以外の任意の文字を表す
{n,m}		n回からm回マッチ
{,n}		0回からn回マッチ
{m,}		m回以上マッチ
[]集合表示
[a-zA-Z]
[0-9]
[^a]		aを取らない

---------------------------------------------------------------------------------------------------------------------------------
# grep -E "a.*c" grep_test.txt 				# 注:.* は前の項目 . に0回または任意回数マッチ
# grep -E "a*c" abc.txt --color=auto		# 注:*  は前の項目 a に0回または任意回数マッチ
# grep -E "a+c" abc.txt --color=auto		# 注:+  は前の項目 a に1回または多回マッチ

二. wc#

wc(単語カウント)コマンド

形式:wc [オプション]... 対象ファイル...

  • -l:行数をカウント
  • -w:単語数をカウント (前後が空白の文字のグループ)
  • -c:文字数をカウント(可視文字と不可視文字)

注:wc はテキスト操作コマンドで、テキストを直接受け取ることができ、cat は必要ありません。

[root@sanchuang-linux ~]# cat wc_test.txt 
a b c
aa bb cc
xyz
1234
aa-bb


--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# wc -l wc_test.txt 	# 注:行数をカウント
5 wc_test.txt
[root@sanchuang-linux ~]# wc -w wc_test.txt 	# 注:単語数をカウント
9 wc_test.txt
[root@sanchuang-linux ~]# wc -c wc_test.txt 	# 注:文字数をカウント
30 wc_test.txt
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# cat wc_test.txt|wc -c		# 書き方2:cat
30
[root@sanchuang-linux ~]# wc -c < wc_test.txt 		# 書き方3:リダイレクト
30

三. diff#

diff コマンド

  • 2 つのファイル間の差異を比較
  • 出力結果は 2 つのファイルの違い

diff コマンドの出力形式

  • 標準 diff
  • -u:異なる部分をまとめて表示し、コンパクトで読みやすい
  • -r: ディレクトリ内のすべてのファイルを再帰的に比較

diff コマンドを使用してパッチを生成

  • diff -u test1 test2 > test.patch
[root@sanchuang-linux ~]# cat diff_1_test.txt
aa
bb
cc
xx
[root@sanchuang-linux ~]# cat diff_2_test.txt
aa
bb
xx

例1
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 
3d2							# 注:3d2  ファイル1の第3行を削除する必要があるので、ファイル2と同じになる
< cc						# 注:ファイル1 のcc
============================================================================================

[root@sanchuang-linux ~]# cat diff_1_test.txt
aa
bb
cc
xx
gg
[root@sanchuang-linux ~]# cat diff_2_test.txt
aa
bb
dd
xx
ee

例2
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 
3c3											# 注:第3行
< cc										# 注:ファイル1 のcc
---
> dd										# 注:ファイル2 のdd
5c5											# 注:第5行
< gg										# 注:ファイル1 のgg
---
> ee										# 注:ファイル2 のee
--------------------------------------------------------------------------------------------
============================================================================================

例3:-u:異なる部分をまとめて表示し、コンパクトで読みやすい
[root@sanchuang-linux ~]# diff -u diff_1_test.txt diff_2_test.txt 
--- diff_1_test.txt	2020-10-30 11:50:45.784010843 +0800
+++ diff_2_test.txt	2020-10-30 11:51:11.475010836 +0800
@@ -1,5 +1,5 @@
 aa
 bb
-cc											# 注:左 - 右 +
+dd											# 注:左側 -cc +dd は右側と同じ
 xx
-gg
+ee

四. patch#

patch コマンド:

  • 用途:ファイルにパッチを適用して修正する
  • 形式:patch [オプション] 元のファイル < パッチファイル
  • -pN: N は N 層のパスを無視することを示す
  • -R: 古いバージョンに戻す

注意事項

  • 複数のパッチを適用する場合、順序に注意
  • パッチを適用する前に元のファイルを変更しないこと

--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# yum install patch
[root@sanchuang-linux ~]# diff diff_1_test.txt diff_2_test.txt 	
3c3							# 注:差異内容
< cc
---
> dd
5c5
< gg
---
> ee

#注:差異ファイルはパッチファイルとも呼ばれる
#注:生成されるのはファイル1のパッチファイル
[root@sanchuang-linux ~]# diff -u diff_1_test.txt diff_2_test.txt > diff_test.patch # 注:1のパッチ
[root@sanchuang-linux ~]# cat diff_test.patch 		#注:パッチファイル
--- diff_1_test.txt	2020-10-30 11:50:45.784010843 +0800
+++ diff_2_test.txt	2020-10-30 11:51:11.475010836 +0800
@@ -1,5 +1,5 @@
 aa
 bb
-cc
+dd
 xx
-gg
+ee
[root@sanchuang-linux ~]# patch diff_1_test.txt < diff_test.patch 	# 注:パッチを適用
patching file diff_1_test.txt
[root@sanchuang-linux ~]# cat diff_1_test.txt 						# 注:パッチを適用
aa
bb
dd
xx
ee
[root@sanchuang-linux ~]# cat diff_2_test.txt 		# 注:ファイル1、2の内容は同じ
aa
bb
dd
xx
ee

五. grep -A\-B#

-A:一致した行とその後の数行を見つける

-B:一致した行とその前の数行を出力する


[root@localhost ~]# grep -A 3 quit /etc/passwd		# 注:一致した行とその後の数行を見つける
[root@localhost ~]# grep -B 3 quit /etc/passwd		# 注:一致した行とその前の数行を出力する

六. free -g#

メモリ使用率を確認する free -g

[root@sanchuang-linux ~]# free -g		# 注:メモリ使用率を確認する、-gは単位G、 -mは単位M
              total        used        free      shared  buff/cache   available
Mem:              1           0           1           0           0           1
Swap:             1           0           1
[root@sanchuang-linux ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1800         272        1101           8         426        1363

七。スクリプトを書く#

以下の機能を実現
1、メモリ使用状況を監視し、使用率が80%を超えた場合に警告を出す
	total free 使用率
2、ローカルネットワークのIPをスキャンし、どのIPアドレスが使用されているかを確認する
	ping -c 1		# 注:1つのパケットを送信
3、ファイル/etc/passwdが変更されていないかを監視し、5分ごとに監視する
	diff
	md5sum	# md5値、ファイルの一意の識別子
4、nginxプロセスが存在するかを監視し、存在しない場合は警告を出す
	pidof nginx
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# md5sum abc.txt 			# 注:md5値
2416b02c3d9d753f48cf49dbb5f1de94  abc.txt
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# pidof nginx				# 注:指定したプログラムのプロセスIDを表示
12767 12766 12765

7.1 メモリ使用状況を監視し、使用率が 80%を超えた場合に警告を出す#

​ total free 使用率


--------------------------------------------------------------------------------------------
#!/bin/bash
function mem(){
    total=`free -m|grep -i mem|tr -s " "|cut -d " " -f2`
    #free=`free -m|grep -i mem|tr -s " "|cut -d " " -f4`
    used=`free -m|grep -i mem|tr -s " "|cut -d " " -f3`
    used_rate=`echo "scale=4;$used/$total" |bc`
    #used_1=`echo "$total*0.8"|bc `
    result=` echo "$used_rate>0.8"|bc `
    echo $result
    if (( $result  == 1  ))
    then
        echo -e "\e[31m使用率が80%を超えました。メモリの拡張を行ってください。無駄な損失を避けるために\e[0m"
    else
        echo  " 何もすることはありません"
    fi
}
mem
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# bash mem_test.sh
0
 何もすることはありません
============================================================================================
知識点7.1.1 bc コマンド
初心者向けチュートリアル:https://www.runoob.com/linux/linux-comm-bc.html
bc コマンドは任意精度計算器言語で、通常はlinuxで計算機として使用されます
[root@localhost ~]# yum install bc -y
[root@localhost ~]# used=`free -m|grep -i mem|tr -s " "|cut -d " " -f3`
[root@localhost ~]# total=`free -m|grep -i mem|tr -s " "|cut -d " " -f2`
[root@localhost ~]# echo "scale=2;$used/$total" |bc	# 注:小数点以下2桁を保持
.16
[root@localhost ~]# echo "scale=3;$used/$total" |bc	# 注:小数点以下3桁を保持
.165
--------------------------------------------------------------------------------------------
[root@localhost ~]# free -m|grep -i mem|tr -s " "|cut -d " " -f2 # 注:-i 大文字と小文字を区別しない
1800
[root@localhost ~]# use_rate=`echo "scale=4;$used/$total" |bc`
[root@localhost ~]# echo "$use_rate>0.8"|bc	# 注:偽の場合は0を返す
0
[root@localhost ~]# echo "0.7>0.8"|bc			# 注:偽の場合は0を返す
0
[root@localhost ~]# echo "0.9>0.8"|bc			# 注:真の場合は1を返す
1		# 注:これはブール値0偽1真を返すべきであり、コマンドの実行失敗の値ではない。$?はすべて0で、コマンドは成功裏に実行された
############################################################################################
知識点7.1.2 小数の演算
小数の演算:
1、bcを使用できます
[root@localhost ~]# echo "scale=3;1/3"|bc		# 注:小数点以下3桁を保持
.333
[root@localhost ~]# echo "0.7>0.8"|bc			# 注:成立しない場合は0を返す
0
[root@localhost ~]# echo "0.9>0.8"|bc			# 注:成立する場合は1を返す
1

2、awk オプション
構文:awk オプション ‘パターン+アクション’ ファイル
一般的なオプション:
-F	区切り文字を指定

組み込み変数
NR	awkでは各行の行番号を表す
NF	awkの列番号

パターン


--------------------------------------------------------------------------------------------
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:           3770         195        3274          11         300        3348
Swap:          2047           0        2047
[root@localhost ~]# free -m|awk 'NR==2{print $2}'		# 注:第2行の第2変数を印刷
3770													# 注:NR 行番号 、 $2 第2変数
[root@localhost ~]# free -m|awk 'NR==2{print $3}'		# 注:第2行の第3変数を印刷
194
============================================================================================
[root@sanchuang-linux ~]# free -m|awk '/Mem/{print $3/$2}'		# 注:小数を計算し、Memをフィルタリング
0.156111														# 注:Memの行をフィルタリング
[root@sanchuang-linux ~]# free -m|awk '/Mem/{printf "%.2f\n", $3/$2}'	# 注:小数点以下2桁を保持
0.16															# 注:\nで改行出力

7.2 ローカルネットワークの IP をスキャンし、どの IP アドレスが使用されているかを確認する#

​ ping -c 1 # 注:1 つのパケットを送信

方法1
--------------------------------------------------------------------------------------------
scan_ip(){
    for ip in `seq 255`
    do
        ( ip_full=192.168.0.$ip
        ping -c 1 $ip_full &>/dev/null && echo $ip_full >>up.txt || echo $ip_full >>down.txt
        ) &	# 注:バックグラウンドで子プロセスを実行
    done
wait # 親プロセスは子プロセスが実行を完了するまで待機
}
scan_ip

方法2
--------------------------------------------------------------------------------------------
scan_ip(){
    for ip in 192.168.0.{1..255}					# 注:1-255はこのように書けます
    do
        ( 
        ping -c 1 $ip &>/dev/null && echo $ip >>up.txt || echo $ip >>down.txt
        ) & 
    done
wait #注:親プロセスは子プロセスが終了するまで待機
}
scan_ip
注:バックグラウンドプロセス
コマンド &	   子bashプロセスを生成してコマンドのタスクを実行
wait		親プロセスは子プロセスが終了するまで待機
============================================================================================

[root@sanchuang-linux ~]# ip=45
[root@sanchuang-linux ~]# ip_full=192.168.0.$ip			# 注:シェル文字列の結合
[root@sanchuang-linux ~]# echo $ip_full 
192.168.0.45
[root@sanchuang-linux ~]# top							# 注:CPUを確認

7.3 nginx プロセスが存在するかを監視し、存在しない場合は警告を出す#

​ pidof nginx


--------------------------------------------------------------------------------------------
check_nginx(){
    pidof nginx && echo "nginxは実行中です" || echo "nginxはダウンしています"
    #if [[ $? -eq 0 ]]
    #then
    #    echo "nginxは実行中です"
    #fi
}
check_nginx
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# pidof nginx
12767 12766 12765
[root@sanchuang-linux ~]# echo $?					# 注:戻り値が0で成功を示す
0

7.4 ファイル /etc/passwd が変更されていないかを監視し、5 分ごとに監視する#

​ diff

​ md5sum # md5 値、ファイルの一意の識別子


--------------------------------------------------------------------------------------------
check_monitor(){
    check_num=`differ /etc/passwd /lianxi/passwd |wc -l`
    [[ check_num -eq 0 ]] && echo "ファイルは変更されていません" || echo "ファイルは変更されました"
}
check_monitor
--------------------------------------------------------------------------------------------
[root@sanchuang-linux ~]# cp /etc/passwd /lianxi/passwd
cp:'/lianxi/passwd'を上書きしますか? y
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd
[root@sanchuang-linux ~]# echo $?	# 注:ファイルが変更されていなくても、戻り値は0(コマンドが成功裏に実行されたことを理解する)
0									# 注:したがって、三項演算子のようなものを使って判断することはできません
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd|wc
      0       0       0
[root@sanchuang-linux ~]# diff /etc/passwd /lianxi/passwd|wc -l
0
#注:判定基準は diff が出力する内容
	出力内容がない場合、wc -l 行数は0で、ファイルが変更されていないことを示します
#注:ファイルが変更されているかどうかはdiffコマンドを考慮する

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。