日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shell脚本:介绍、语法、运算、流程控制、对文件/输出流处理、案例

發(fā)布時(shí)間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shell脚本:介绍、语法、运算、流程控制、对文件/输出流处理、案例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • Shell介紹
    • shell腳本的命令
    • 運(yùn)行shell腳本
    • 特殊符號(hào)
    • 管道符
    • 重定向
  • 格式化輸入與輸出
    • 格式化輸出
  • 運(yùn)算
    • shell數(shù)學(xué)運(yùn)算
    • 變量
    • 數(shù)組
    • 五大運(yùn)算
  • 循環(huán)與流程控制
    • if
    • for循環(huán)
    • 循環(huán)控制語句
    • while循環(huán)
    • until循環(huán)
    • case多分支語句
  • shell其他知識(shí)
    • shell函數(shù)
    • 正則表達(dá)式
    • 對(duì)文件的操作
    • 對(duì)文件的補(bǔ)充
    • 對(duì)輸出流處理
        • awk命令基本用法
        • awk命令高級(jí)用法
        • awk流程控制與循環(huán)
  • 腳本案例
    • 監(jiān)控一個(gè)主機(jī)的存活狀態(tài)
    • 監(jiān)控端口存活狀態(tài)
    • 監(jiān)控內(nèi)存使用率
    • 使用cpu或內(nèi)存前十的進(jìn)程

Shell介紹

shell是一個(gè)程序、采用c語言編寫,是用戶和linux內(nèi)核溝通的橋梁。它既是一種命令語言,又是一種解釋性的編程語言。

內(nèi)核是管理電腦的所有硬件,同時(shí)內(nèi)核還要負(fù)責(zé)驅(qū)動(dòng)硬件干活,就比如說我們需要打印一張照片,內(nèi)核就會(huì)驅(qū)動(dòng)打印機(jī)去干活。這是內(nèi)核的兩個(gè)主要的功能。用戶下指令給內(nèi)核,內(nèi)核再讓相應(yīng)的硬件設(shè)備去干活,但是用戶與內(nèi)核的語言不通,內(nèi)核只認(rèn)識(shí)機(jī)器語言,而用戶是高級(jí)語言,shell的作用就體現(xiàn)在這里了,它就是解釋命令的。

shell功能:

  • 命令行解釋功能
  • 啟動(dòng)程序
  • 輸入輸出重定向
  • 管道連接
  • 文件名置換
  • 變量維護(hù)
  • 環(huán)境控制
  • shell編程


  • # Shell語法 hell腳本就是將完成一個(gè)任務(wù)的所有的命令按照?qǐng)?zhí)行的先后順序,自上而下寫入到一個(gè)文本文件中,然后給予執(zhí)行權(quán)限。

    這就是shell腳本的本質(zhì),現(xiàn)在做一個(gè)案例,編寫一個(gè)shell腳本 用來安裝nginx。

    我先創(chuàng)建一個(gè)shell的文件夾,接下來所有有關(guān)shell的練習(xí)都在這里面。/home/hs/shell

  • 首先在Nginx的官網(wǎng)中復(fù)制一個(gè)安裝包的下載鏈接

  • 在練習(xí)shell的目錄下創(chuàng)建一個(gè)文件vim nginx_install.sh

  • #!/usr/bin/bash # 安裝nginx步驟: # 1. 要安裝nginx,首先需要安裝依賴 yum -y install wget gcc pcre-devel zlib-devel # 2. 下載nginx wget https://nginx.org/download/nginx-1.20.1.tar.gz # 3. 解壓nginx壓縮包 tar xf nginx-1.20.1.tar.gz # 4. 進(jìn)入解壓后的目錄 cd nginx-1.20.1 # 5. 執(zhí)行configure文件 ./configure --prefix=/use/local/nginx # 最后執(zhí)行make命令 make make install
  • 給文件執(zhí)行權(quán)限

    [root@VM-8-7-centos shell_01]# chmod 700 nginx_install.sh
  • 然后在執(zhí)行剛剛創(chuàng)建的shell腳本

    [root@VM-8-7-centos shell_01]# pwd /home/hs/shell/shell_01 [root@VM-8-7-centos shell_01]# ls aaa_explain.txt nginx_install.sh [root@VM-8-7-centos shell_01]# ./nginx_install.sh
  • 安裝完成之后然后在啟動(dòng)

    # nginx的常用命令 cd /usr/local/nginx/sbin/ ./nginx 啟動(dòng) ./nginx -s stop 停止 ./nginx -s quit 安全退出 ./nginx -s reload 重新加載配置文件 ps aux|grep nginx 查看nginx進(jìn)程
  • 然后在通過瀏覽器訪問,就能出現(xiàn)如下界面


  • shell腳本的命令

  • 文件名盡量見名知意,不要瞎起

  • 在shell腳本的第一行盡量使用#! 寫一段定義腳本的執(zhí)行環(huán)境。#! 在shell中是一個(gè)特例,這不是注釋 。 這是定義該shell腳本在哪個(gè)環(huán)境下執(zhí)行 寫在第一行

  • # 表示注釋 在以后的shell腳本執(zhí)行時(shí),請(qǐng)不要再里面寫中文 即使是注釋也不要寫中文

  • 在定義腳本的執(zhí)行環(huán)境下還需要加一下的提示信息

    #!/usr/bin/bash # Author:Hu Shang # Created Time: 2021/8/24 19:27 # Script Description: nginx install script
  • 腳本的組成:

    • 解釋環(huán)境
    • 注釋說明
    • 執(zhí)行代碼

    運(yùn)行shell腳本

    運(yùn)行shell腳本有兩種方式:

    • 給執(zhí)行權(quán)限
    • 使用解釋器直接運(yùn)行,這種方式就不需要給執(zhí)行權(quán)限了

    比如我現(xiàn)在創(chuàng)建一個(gè)入門文件,輸入hello world!

    vim shell_helloWorld.sh

    #!/usr/bin/bash # Author:Hu Shang # created Time: 2021/8/24 19:49 # script Description: shell hello world!!echo "hello world!"

    我現(xiàn)在可以使用chmod 700 shell_helloWorlf.sh 命令給改文件設(shè)置執(zhí)行權(quán)限 然后直接./shell_helloWorld.sh

    另一種方式就是:

    給該文件不設(shè)置執(zhí)行權(quán)限chmod 644 shell_helloWorlf.sh,然后使用

    # 先沒有設(shè)置執(zhí)行權(quán)限,然后利用bash命令 使用解釋器也可以運(yùn)行 然后就出現(xiàn)了下面的輸入語句 [root@VM-8-7-centos shell_01]# chmod 644 shell_helloworld.sh [root@VM-8-7-centos shell_01]# bash shell_helloworld.sh hello world!# 處理bash 我還可以使用sh 解釋器來運(yùn)行shell腳本, 下面六種都支持 但是建議腳本中第一行指定的什么執(zhí)行環(huán)境就使用什么 [root@VM-8-7-centos shell_01]# sh shell_helloworld.sh hello world! [root@VM-8-7-centos shell_01]# cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash /bin/tcsh /bin/csh

    bash -x 文件名 以debug模式運(yùn)行shell腳本


    特殊符號(hào)

    • ~ 進(jìn)入到家目錄 比如 cd ~

    • ! 執(zhí)行歷史命令 !! 這是執(zhí)行上一條命令

    • $ 變量中取內(nèi)容符 比如我想知到當(dāng)前用戶是誰echo $USER

    • + - * / % 對(duì)應(yīng)數(shù)學(xué)中的加減乘除取余

    • & 后臺(tái)執(zhí)行

    • * 通配符 shell中匹配所有字符

    • ? 通配符 shell中匹配除回車之外的單個(gè)字符

    • ; 如果在一行中需要執(zhí)行多條命令就需要使用分號(hào)

    • | 管道符 上一個(gè)命令的輸出作為下一個(gè)命令的輸入 例如 cat filename|grep "abc"

    • \ 轉(zhuǎn)義字符

    • `` 這兩個(gè)反引號(hào) 作用是在命令中執(zhí)行命令

      [root@VM-8-7-centos ~]# echo -n “date is:”;date +%F date is:2021-08-24 [root@VM-8-7-centos ~]# echo "date is: `date +%F`" date is: 2021-08-24
    • ' ' 單引號(hào) 腳本中出現(xiàn)的字段可以用單引號(hào)引起來 單引號(hào)不解釋變量

    • " " 雙引號(hào) 腳本中出現(xiàn)的字段可以用雙引號(hào)引起來

      [root@VM-8-7-centos ~]# echo 'date is: `date +%F`' date is: `date +%F` [root@VM-8-7-centos ~]# echo "date is: `date +%F`" date is: 2021-08-24 # 這就是區(qū)別 如果用單引號(hào) 那就是原樣輸出 不會(huì)去解釋變量


    管道符

    管道符 | 在shell中是使用的很多的,管道就是上一個(gè)命令的輸出作為下一個(gè)命令的輸入。

    比如我要查看這個(gè)文件的內(nèi)容,命令如下:

    [root@VM-8-7-centos shell_01]# cat shell_helloworld.sh #!/usr/bin/bash # Author:Hu Shang # created Time: 2021/8/24 19:49 # script Description: shell hello world!!echo "hello world!"

    但是如果我不想輸出改文件了,我想把這個(gè)通過管道符 輸入給grep 命令 讓改命令檢索某個(gè)字符串,

    他就會(huì)把這段文字中包含某個(gè)字符串的這一行內(nèi)容找出來

    [root@VM-8-7-centos shell_01]# cat shell_helloworld.sh | grep "hello world" # script Description: shell hello world!! echo "hello world!"

    重定向

    首先是重定向輸入

    # 將haha字符串輸入到test.txt文件中 [root@VM-8-7-centos shell_01]# echo haha > ./test.txt # 但是這個(gè)命令是一次性輸入,這條命令會(huì)先將文件內(nèi)容清空,然后進(jìn)行輸入操作。如果我在使用它輸入其他字符串,就會(huì)把上一次輸入的內(nèi)容替換掉 # 如果我不想清空原來的內(nèi)容 想進(jìn)行追加的操作:就需要使用 >> [root@VM-8-7-centos shell_01]# echo haha > test.txt [root@VM-8-7-centos shell_01]# cat test.txt haha [root@VM-8-7-centos shell_01]# echo aaa >> test.txt [root@VM-8-7-centos shell_01]# echo bbb >> test.txt [root@VM-8-7-centos shell_01]# cat test.txt haha aaa bbb

    接下來是重定向輸出

    就比如我使用wc命令來統(tǒng)計(jì)一個(gè)文件的 行數(shù) 單詞數(shù) 字節(jié)數(shù)

    [root@VM-8-7-centos shell_01]# wc < ./test.txt 3 3 13

    這行命令是把這個(gè)文件的內(nèi)容從內(nèi)容中輸出給 wc 它再進(jìn)行統(tǒng)計(jì)

    # 這個(gè)統(tǒng)計(jì)的是數(shù)據(jù)流 [root@VM-8-7-centos shell_01]# wc < ./test.txt 3 3 13# 這里統(tǒng)計(jì)的是文本 [root@VM-8-7-centos shell_01]# wc ./test.txt 3 3 13 ./test.txt

    追加輸出
    我要寫一個(gè)有關(guān)與磁盤分區(qū)相關(guān)的腳本

    [root@VM-8-7-centos shell_01]# vim disk_partition.sh

    腳本內(nèi)容為:

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021/8/25 20:57 # Script Description: harddisk partition scriptfdisk /dev/sdb <<EOF n p 3+534M w EOF

    重定向追加輸出,用 <<

    • 然后使用EOF或者是END充當(dāng)左右括號(hào) 將要輸入的內(nèi)容括起來
    • 將我們要交互的內(nèi)容 頂格寫在EOF中


    格式化輸入與輸出

    格式化輸出

    echo 該命令負(fù)責(zé)輸出,將內(nèi)容輸出到默認(rèn)顯示設(shè)備

    語法: echo [-n -e] 字符串

    echo命令將字符串輸出之后會(huì)直接換行

    命令選項(xiàng):

    • -n 不要再最后換行
    • -e 讓字符串支持轉(zhuǎn)義字符,如果不加該屬性,字符串中即使有轉(zhuǎn)義字符也只會(huì)把它當(dāng)成普通字符串輸出

    轉(zhuǎn)義字符:

    \a 發(fā)出報(bào)警

    \b 刪除前一個(gè)字符

    \c 最后不加換行

    \f \v 換行,但光標(biāo)仍停留在原來的位置

    \n 換行,且光標(biāo)移至行首

    \r 光標(biāo)移至當(dāng)前行首,不會(huì)換行

    \t 制表位

    \nnn 插入nnn(八進(jìn)制)所代表的ASCII字符

    一個(gè)輸出倒計(jì)時(shí)的案例

    #!/usr/bin/bash # Author: hushang # Created Time: 2021-08-26 19:00 # Script Description: number downfor time in `seq 9 -1 0`;doecho -n -e "$time"sleep 1echo -n -e "\b" doneecho

    顏色代碼

    讓輸出的字符串加上一些背景顏色 字體顏色

    echo -e "\033[背景色;字體顏色m 字符串 \033[字體效果m"# 字符串前后可以沒有空格,如果有的話,輸出也是同樣有空格[root@VM-8-7-centos shell_02]# echo -e "\033[44;31m 你好呀 \033[0m"你好呀



    我在最后給輸出的字符串加上了下劃線的選項(xiàng),導(dǎo)致了下面的命令都有改樣式了,我只需要將最后一個(gè)樣式 變?yōu)?m 即可


    ## 格式化輸入 `read` 命令 默認(rèn)接受鍵盤的輸入,回車符代表輸入結(jié)束

    當(dāng)shell腳本執(zhí)行到read命令時(shí)就不會(huì)執(zhí)行了,會(huì)停下來

    命令選項(xiàng):

    • -p 打印信息

    • -t 限定時(shí)間

      read -t5 temp 有輸入就存放在temp變量中,如果五秒中沒有輸入那就不會(huì) 一直等待了

    • -s 不回顯, 就比如輸入密碼時(shí) 別人就看不到你輸入的內(nèi)容了

    • -n 輸入字符個(gè)數(shù)

      read -n5 temp 這就是只能輸入五位數(shù),只能識(shí)別輸入的五位數(shù),當(dāng)用戶輸入五位數(shù)后程序就自動(dòng)往下運(yùn)行了

    案例 寫一個(gè)簡(jiǎn)單的登錄

    vim login.sh

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-26 20:28 # Script Discrption: test input,loginclear echo -n -e "login: " read echo -n -e "password: " read

    然后執(zhí)行該腳本

    [root@VM-8-7-centos shell_02]# bash login.sh login: 123 password: 123 [root@VM-8-7-centos shell_02]#

    但是現(xiàn)在的問題的,我們輸入的內(nèi)容的確的輸入了,并且放在了內(nèi)存中,可是并沒有定位,根本不知道存放的位置,也就使用不了,所以需要使用一個(gè)邏輯變量名

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-26 20:28 # Script Discrption: test input,loginclear echo -n -e "login: " read acc echo -n -e "password: " read passecho "username: $acc password: $pass" # 這里就能將我上面的輸入拿來用了。

    這其實(shí)就是一個(gè)變量,變量就是在內(nèi)存中找一塊位置,做一個(gè)定位,定好位后就將我們輸入的內(nèi)容存到該定位中

    我每次都需要使用兩個(gè)語句: echo 和 read 這兩個(gè)命令可以結(jié)合為一條命令 也就是上方的-p 命令參數(shù)

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-26 20:28 # Script Discrption: test input,loginclear # echo -n -e "login: " # read acc read -p "login: " acc echo -n -e "password: " read passecho "username: $acc password: $pass" # 這里就能將我上面的輸入拿來用了。

    運(yùn)算

    shell數(shù)學(xué)運(yùn)算

    expr 這個(gè)命令是用來做數(shù)學(xué)運(yùn)算的

    # 該命令有很嚴(yán)格是空格要求 [root@VM-8-7-centos shell_01]# expr 1+1 1+1 # 參與運(yùn)算的數(shù)與運(yùn)算符之間都需要空格 [root@VM-8-7-centos shell_01]# expr 1 + 1 2 # 參與運(yùn)算的數(shù)必須是整數(shù) [root@VM-8-7-centos shell_01]# expr 1 + 1.1 expr: non-integer argument # 乘法必須轉(zhuǎn)義 [root@VM-8-7-centos shell_01]# expr 1 * 2 expr: syntax error [root@VM-8-7-centos shell_01]# expr 1 \* 2 2 [root@VM-8-7-centos shell_01]# expr 10 / 2 5 [root@VM-8-7-centos shell_01]# expr 10 % 3 1

    比如,我要判斷一個(gè)數(shù)是否為整數(shù)

    # 可以先讓要判斷的數(shù) +1 [root@VM-8-7-centos shell_01]# expr 8 + 1 9 # $? 是判斷上一條命令是否執(zhí)行成功,如果是0就表示執(zhí)行成功 如果是 [root@VM-8-7-centos shell_01]# echo $? 0 # 執(zhí)行失敗的情況 [root@VM-8-7-centos shell_01]# expr 7 + 7.1 expr: non-integer argument [root@VM-8-7-centos shell_01]# echo $? 2 # 還可以將上一條命令的輸出 不進(jìn)行輸出 讓它輸出到回收站中去。然后判斷上一條命令是否執(zhí)行成功 [root@VM-8-7-centos shell_01]# expr 7 + 7.1 &>/dev/null ; echo $? 2

    數(shù)學(xué)運(yùn)算還有另一個(gè)命令let ,它必須將結(jié)果賦值到一個(gè)變量中去,然后進(jìn)行其他操作

    [root@VM-8-7-centos shell_01]# let sum=1+2+3 [root@VM-8-7-centos shell_01]# echo $sum 6

    let 命令也是整數(shù)的運(yùn)算

    但是在shell中難免會(huì)出現(xiàn)小數(shù)的運(yùn)算,就可以使用bc 計(jì)算器

    [root@VM-8-7-centos shell_01]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 1+1 213-11 24/2 23*3 9# 但是bc計(jì)算器默認(rèn)也不支持小數(shù)運(yùn)算,需要使用下面的命令指定一個(gè)小數(shù)位,然后就可以執(zhí)行小數(shù)運(yùn)算了 scale=2 10/3 3.33

    但bc 計(jì)算器是一個(gè)交互界面,shell腳本中不能交互,這就用到了管道

    [root@VM-8-7-centos shell_01]# echo "scale=2;10/4" | bc 2.50[root@VM-8-7-centos shell_01]# echo "百分?jǐn)?shù):`echo "scale=2;10/2"|bc`%" 百分?jǐn)?shù):5.00%

    在shell下 $(( )) 就可以做運(yùn)算

    [root@VM-8-7-centos shell_01]# $(( 10+20)) -bash: 30: command not found [root@VM-8-7-centos shell_01]# echo $(( 10+50)) 60 [root@VM-8-7-centos shell_01]# echo $((10/3)) 3 [root@VM-8-7-centos shell_01]# echo $((10%3)) 1

    ?

    變量

    在編程中,我們總有一些數(shù)據(jù)需要臨時(shí)存放在內(nèi)存中,以待后續(xù)使用時(shí)快速讀出。內(nèi)存在系統(tǒng)啟動(dòng)的時(shí)候按照1B一個(gè)單位劃分為若干塊,然后統(tǒng)一編號(hào)(16進(jìn)制編號(hào)),并對(duì)內(nèi)存的使用情況做記錄,保存在內(nèi)存跟蹤表中。

    假如我將1B的字符存入內(nèi)存中,如何讀取出來?就是通過變量的

    變量:是編程中最常用的一種臨時(shí)在內(nèi)存中存取數(shù)據(jù)的一種方式

    就比如我們 0X3 這個(gè)位置是內(nèi)存中的第三塊,計(jì)算機(jī)認(rèn)識(shí),可以我們不知道,那么我們就可以為這塊區(qū)域起一個(gè)邏輯名字,然后在往這塊區(qū)域中存值。到時(shí)候取值也可以使用0X3 這個(gè)物理地址 也可以使用我們定義的邏輯名字

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-h7MlVWYo-1631417107601)(E:\Java筆記\picture\image-20210827132419037.png)]

    所以變量就是內(nèi)存中一塊地址的一個(gè)邏輯名字。

    當(dāng)我們從腳本中定義變量存值,可以從以下方面看到變化:

  • 內(nèi)存占用:如果存的是一個(gè)字符則占用一個(gè)字節(jié),如果存的是字符串這占用長(zhǎng)度+1個(gè)字節(jié)。因?yàn)樽詈笥幸粋€(gè)'\0'代表結(jié)束標(biāo)識(shí)

  • 變量名與空間的對(duì)應(yīng)關(guān)系:計(jì)算機(jī)會(huì)將對(duì)應(yīng)的內(nèi)存空間和變量名綁定在一起,此時(shí)代表這段空間已經(jīng)被程序占用,其他程序不可用,然后將變量名對(duì)應(yīng)的值存入對(duì)應(yīng)的內(nèi)存空間。


  • 變量的分類

    • 本地變量:用戶私有變量,只有本用戶可以使用,保存在家目錄下的.bash_profile 、 .bashrc 文件中。用戶登錄成功后才將命令加載進(jìn)內(nèi)存
    • 全局變量:所有用戶都可以使用,保存在/etc/profile 、 /etc/bashrc 文件中。在用戶登錄之前就加載進(jìn)內(nèi)存中
    • 用戶自定義變量: 用戶自定義,比如腳本中的變量。

    建議變量的命名采用大寫 和命令區(qū)分。

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-27 21:14 # Script Discription: test user custom variable# 這里定義幾個(gè)變量 NAME='Hu Shang' AGE=21 SCORE=100# 這里讀取 echo "name=$NAME , age=$AGE"

    定義變量

    格式:變量名=值

    注意:

    • shell編程中變量名與等號(hào)之間不能有空格,
    • 變量的命名參照java命名規(guī)范,不能將變量名定義為bash中的命令(保留關(guān)鍵字)
    • 字符串要用單引號(hào)或雙引號(hào) 引起來。
    • shell是區(qū)分大小寫的,建議將變量命名全改為大寫,這樣可以和命令區(qū)分開

    讀取變量?jī)?nèi)容

    可以通過 $ 來讀取變量中的內(nèi)容 格式:$變量名


    取消變量

    unset 變量名

    當(dāng)我們定義了一個(gè)變量,然后不想使用了,可以將電腦關(guān)機(jī) 存在內(nèi)存中的變量就沒了,也可以使用unset 命令來實(shí)現(xiàn)

    [root@VM-8-7-centos shell_02]# NAME='胡 尚' [root@VM-8-7-centos shell_02]# echo $NAME 胡 尚 [root@VM-8-7-centos shell_02]# unset NAME [root@VM-8-7-centos shell_02]# echo $NAME[root@VM-8-7-centos shell_02]#

    使用這個(gè)命令可以取消用戶自定義變量和本地變量、全局變量。比如我現(xiàn)在定義一個(gè)全局變量:

  • 在/etc/profile目錄下添加一個(gè)變量

    # 首先在/etc/profile 文件下添加變量 vim /etc/profile# 第二個(gè) 添加變量 # 這樣定義的一個(gè)變量 即使是在/etc/profile 文件中定義的變量,但其實(shí)還是一個(gè)本地變量,其他用戶還是使用不了 NAME='胡 尚' # 需要加上export 關(guān)鍵字 export NAME='胡 尚'# 修改了這個(gè)文件 還需要使用source命令讓它生效 source /etc/profile

  • 定義永久變量

    寫在命令行就是臨時(shí)變量,關(guān)機(jī)重啟就沒了 如果想定義永久變量就定義在上面提到的文件中


    特殊變量

    • $0 代表當(dāng)前腳本的名字
    • $1 $2 … 代表傳參
    • $* 代表所有的參數(shù),其間隔為IFS內(nèi)定參數(shù)的第一個(gè)字元
    • @與@ 與@*相同 不同之處在于不參照IFS
    • $# 參數(shù)的數(shù)量
    • $ 執(zhí)行上一條指令的返回值
    • $$ 腳本執(zhí)行進(jìn)程號(hào)
    • $_ 顯示出最后一個(gè)執(zhí)行命令

    數(shù)組

    變量和數(shù)組的區(qū)別就是,變量一次只能存一個(gè)值,數(shù)組一次可以存多個(gè)值。


    基本數(shù)組

    可以讓用戶一次性賦予多個(gè)值,使用時(shí)通過索引來調(diào)用值

    定義格式:數(shù)組名=(元素1 元素2 元素3 ...)

    數(shù)組的讀取:${數(shù)組名[索引]} 索引從0開始

    數(shù)組的賦值:

    • 一次性賦值多個(gè) 數(shù)組名=(元素1 元素2 元素3 ...)
    • 一次性賦值一個(gè) 數(shù)組名[索引]= 元素

    訪問數(shù)組元素:

    • echo ${數(shù)組名[0]} 訪問數(shù)組中第一個(gè)元素
    • echo ${數(shù)組名[@]} 訪問數(shù)組中全部元素
    • echo ${#數(shù)組名[0]} 統(tǒng)計(jì)數(shù)組元素個(gè)數(shù)
    • echo ${數(shù)組名[@]:2} 從索引為2的位置開始打印數(shù)組中的所有元素
    • echo ${數(shù)組名[@]:2:4} 從索引為2的位置開始打印 共打印4個(gè)元素
    • echo ${!數(shù)組名[@]} 獲取數(shù)組元素的索引
    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 10:56 # Script Discrption: arrayARRAY1=('a' 'b' 'c' 'd') ARRAY1[4]='e' # 等號(hào)前后都不要有空格 ARRAY1[5]='f'echo "根據(jù)數(shù)據(jù)索引來獲取值:" echo ${ARRAY1[0]} echo "獲取全部值:" echo ${ARRAY1[@]} echo "獲取數(shù)組長(zhǎng)度:" echo ${#ARRAY1[@]} echo "從索引為2的位置開始打印:" echo ${ARRAY1[@]:2} echo "從索引為2的位置開始打印,共打印3個(gè)" echo ${ARRAY1[@]:2:3} echo "輸出數(shù)組的索引:" echo ${!ARRAY1[@]}

    輸出結(jié)果為:

    [root@VM-8-7-centos shell_02]# bash array.sh 根據(jù)數(shù)據(jù)索引來獲取值: a 獲取全部值: a b c d e f 獲取數(shù)組長(zhǎng)度: 6 從索引為2的位置開始打印: c d e f 從索引為2的位置開始打印,共打印3個(gè) c d e 輸出數(shù)組的索引: 0 1 2 3 4 5

    索引也可以自定義,但是就需要使用到關(guān)聯(lián)數(shù)組了


    關(guān)聯(lián)數(shù)組

    關(guān)聯(lián)數(shù)組允許用戶自定義索引,這樣使用起來更方便 高效。在創(chuàng)建關(guān)聯(lián)數(shù)組時(shí)需要先聲明,如果不聲明那么創(chuàng)建的就是一個(gè)基本數(shù)組

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 11:25 # Script Discription: associate array# 聲明一個(gè)關(guān)聯(lián)數(shù)組 declare -A ASS_ARRAY1 # 然后一次性賦一個(gè)值 ASS_ARRAY1[name]='hushang' ASS_ARRAY1[age]=21 echo ${ASS_ARRAY1[name]}# 聲明第二個(gè)關(guān)聯(lián)數(shù)組 一次性賦多個(gè)值 declare -A ASS_ARRAY2 ASS_ARRAY2=([name]='aaaaa' [age]=22) echo "第二個(gè)關(guān)聯(lián)數(shù)組的name屬性值是:${ASS_ARRAY2[name]}"

    五大運(yùn)算


    數(shù)學(xué)比較運(yùn)算

    這里比較是的整形。

    • -eq 等于
    • -gt 大于
    • -lt 小于
    • -ge 大于等于
    • -le 小于等于
    • ne 不等于
    # test命令可以用來做判斷 但是不會(huì)輸出結(jié)果 可以使用echo $? 輸出上一條命令的結(jié)果, 如果為0就表示成功 非0表示失敗 [root@VM-8-7-centos shell_02]# test 1 -eq 1; echo $? 0 [root@VM-8-7-centos shell_02]# test 1 -gt 1; echo $? 1 [root@VM-8-7-centos shell_02]# test 1 -ge 1; echo $? 0 [root@VM-8-7-centos shell_02]# test 1 -lt 1; echo $? 1 [root@VM-8-7-centos shell_02]# test 1 -le 1; echo $? 0 [root@VM-8-7-centos shell_02]# test 1 -ne 1; echo $? 1 [root@VM-8-7-centos shell_02]#

    如果某種情況下需要進(jìn)行小數(shù)比較,可以先轉(zhuǎn)換為整數(shù) 然后在比較,就比如1.5 和 2 進(jìn)行比較,都*10 然后比較就可以了

    [root@VM-8-7-centos shell_02]# echo "1.5*10"|bc 15.0# cut -d 數(shù)字 分割命令 以 . 進(jìn)行分割 -f1 是表示取分割都的第一個(gè) [root@VM-8-7-centos shell_02]# echo "1.5*10"|bc|cut -d '.' -f1 15[root@VM-8-7-centos shell_02]# test `echo "1.5*10"|bc|cut -d '.' -f1` -lt $((2*10));echo $? 0

    字符串比較運(yùn)算

    首先字符串別忘了用雙引號(hào)引起來,

    • == 等于
    • != 不等于
    • -n 檢查字符串長(zhǎng)度是否大于0
    • -z 檢查字符串長(zhǎng)度是否為0
    [root@zutuanxue ~]# test 'root' == 'root';echo $? 0 [root@zutuanxue ~]# test 'root' != 'root1';echo $? 0 [root@zutuanxue ~]# test -n "$name";echo $? 1 [root@zutuanxue ~]# test -z "$name";echo $? 0

    文件比較與檢查

    -d 檢查目錄是否存在 -e 檢查文件或目錄是否存在 -f 檢查文件是否存在 -r 檢查文件是否存在且可讀 -s 檢查文件是否存在且不為空 -w 檢查文件是否存在且可寫 -x 檢查文件是否存在且可執(zhí)行 -O 檢查文件是否存在并且被當(dāng)前用戶擁有 -G 檢查文件是否存在并且默認(rèn)組為當(dāng)前用戶組 -nt file1 -nt file2 檢查file1是否比file2新 -ot file1 -ot file2 檢查file1是否比file2舊 -ef file1 -ef file2 檢查file1是否與file2是同一個(gè)文件,判定依據(jù)的是i節(jié)點(diǎn)以上只列出部分命令選項(xiàng),詳細(xì)的可以通過:man test獲得。

    邏輯運(yùn)算

    • && 邏輯與
    • || 邏輯或
    • ! 邏輯非

    賦值運(yùn)算

    • = 賦值運(yùn)算符, 盡量在shell中前后就不要加空格了。


    循環(huán)與流程控制

    if


    語法一:單if語句

    滿足條件后執(zhí)行一些命令,這里的條件就是上面的五大運(yùn)算 一般也就是 數(shù)字 字符串 文件 這三個(gè)的比較判斷

    if [ condition ] # 兩個(gè)中括號(hào)中需要有空格 thencommands fi

    寫一個(gè)腳本,當(dāng)/tmp/abc這個(gè)目錄不存在時(shí)就創(chuàng)建它

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 16:14 # Script Description: 測(cè)試if 如果/tmp/abc 這個(gè)目錄不存在就創(chuàng)建一個(gè)if [ ! -d /tmp/abc ]thenmkdir -v /tmp/abcecho "create /tmp/abc success" fi

    if-then-else語句

    滿足條件后執(zhí)行一些命令,如果不滿足就執(zhí)行另一些

    if [ condition ] # 兩個(gè)中括號(hào)中需要有空格 thencommands1elsecommands2 fi

    還是上面創(chuàng)建目錄的案例

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 16:14 # Script Description: 測(cè)試if 如果/tmp/abc 這個(gè)目錄不存在就創(chuàng)建一個(gè) 如果存在就提示if [ ! -d /tmp/abc ]thenmkdir -v /tmp/abcecho "create /tmp/abc success" elseecho "creat /tmp/abc fail"echo "the dir already exist" fi

    if-then-elif語句

    if [ conditon ]thencommands1elif [ condition ]thencommands2elif [ condition ]thencommands3…… elsecommandsN fi

    案例如下

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 16:51 # Script Description: 測(cè)試 if then elif 語句 輸入兩個(gè)數(shù) 然后比較大小if [ $1 -eq $2 ]thenecho "$1 == $2" elif [ $1 -gt $2 ]thenecho "$1 > $2" elseecho "$1 < $2" fi

    這里在執(zhí)行這個(gè)腳本時(shí),還可以在后面加上兩個(gè)值 表示腳本中的$1 與 $2 兩個(gè)變量

    [root@VM-8-7-centos shell_02]# bash test_if_compare.sh 1 1 1 == 1 [root@VM-8-7-centos shell_02]# bash test_if_compare.sh 1 2 1 < 2 [root@VM-8-7-centos shell_02]# bash test_if_compare.sh 1 0 1 > 0

    其他用法

    條件符號(hào)使用雙小圓括號(hào),可以在條件中植入數(shù)學(xué)表達(dá)式。需要注意的就是 在雙小圓括號(hào)中 比較是使用的我們傳統(tǒng)的符號(hào) 而不是 -gt 這種

    # if的另一用法 用兩個(gè)小括號(hào) 可以用來做整數(shù)的判斷 if (( 100+20 > 150 ));thenecho "yes" elseecho "no" fi

    使用雙方括號(hào),可以在條件中使用通配符 可以做字符串匹配

    # if 的另一種用法 使用兩個(gè)方括號(hào) 可以用通配符 # 使用循環(huán) 將 rx開頭的字符串打印出來 for TEMP_VAR in aaa abc dede rxaa rxbb rxccdoif [[ "$TEMP_VAR" == rx* ]];thenecho "$TEMP_VAR"fi done

    程序的判斷越多 越智能。


    for循環(huán)


    for語法一

    for 變量名 in value1 value2 ...do命令段 done

    這個(gè)意思是,將in后面的值依次賦值給前面的臨時(shí)變量,然后執(zhí)行一次命令段,再賦值下一個(gè)value,在執(zhí)行一次

    #!/usr/bin/bash # Author: hu shang # Created Time: 2021-08-28 18:09 # Script Description: for循環(huán)的練習(xí) # 輸出 1 - 9 之間的數(shù) for var in `seq 1 9`doecho "$var" done

    seq 這個(gè)命令 就是一個(gè)數(shù)數(shù)的命令

    [root@VM-8-7-centos shell_02]# seq 1 5 1 2 3 4 5 [root@VM-8-7-centos shell_02]# seq 5 -1 1 5 4 3 2 1

    語法二

    for ((變量;條件;自增自減))do代碼段 done# 輸出1-9 的腳本如下 for ((i=1;i<10;i++))doecho "$i" done# 當(dāng)有多個(gè)字段時(shí),也和java沒什么區(qū)別 for ((i=1,j=9;i<10,j>0;i++,j--))doecho "$i --- $j" done

    循環(huán)控制語句

    • sleep N 休眠N秒鐘
    • continue 跳出本輪循環(huán)
    • break 終止循環(huán)
    #!/usr/bin/bash # Author: hushang # Created Time: 2021-8-30 12:46 # Script Description: 循環(huán)控制 sleep continue break# 每隔一秒輸出1-9 但是跳過5 for ((i=1;;i++))do# 是否等于5if [ $i -eq 5 ]thencontinuefi# 大于9就跳出循環(huán)if [ $i -gt 9 ]thenbreakfiecho $isleep 1 done

    break 后面還可以跟一個(gè)數(shù)字

    for ((;;))doecho "aaa"for ((;;))doecho "bb"break 2 # 這里如果寫1 就表示跳過離break最近的這個(gè)內(nèi)循環(huán) 如果寫2 這里就表示跳出外循環(huán)了done done

    while循環(huán)

    如果明確知道了循環(huán)的次數(shù)就推薦使用for,如果不知道循環(huán)次數(shù)還是推薦使用while循環(huán)。

    語法:

    while [ condition ] do循環(huán)體 done# 可以在多個(gè)條件之間使用邏輯運(yùn)算符 while [ condition ] && [ condition ]do循環(huán)體 done

    while還有一些嵌套使用,還是比較簡(jiǎn)單,嵌套if while for


    until循環(huán)

    until循環(huán)和while循環(huán)語法上一樣,區(qū)別是,while是當(dāng)條件為true時(shí)繼續(xù)循環(huán),而until剛好相反,條件為false時(shí)才循環(huán)

    until [ condition ] do循環(huán)體 done

    case多分支語句

    語法:

    case 變量 in 條件1) 代碼段 ;; 條件2)代碼段 ;; ...... # 如果都不滿足 則執(zhí)行默認(rèn)的代碼段 *)代碼段 ;; esac# 每個(gè)代碼塊執(zhí)行完使用;;結(jié)尾, case開始 esac倒過來寫表示改語句結(jié)束

    小案例

    #!/usr/bin/bash # Author: hushang # Created Time: 2021-08-31 13:04 # Script Description: case多分支語句的練習(xí) 根據(jù)用戶輸入的值來輸出對(duì)應(yīng)的字符串for ((;;)) doread -p "number: " Ncase $N in1)echo "aaaaa";;2)echo "bbbbb";;3)echo "ccccc";;4)break;;*)echo "輸入有誤,請(qǐng)輸入{1|2|3|4} 輸入4退出";;esac done # 如果當(dāng)有多個(gè)條件中的任意一個(gè)滿足就執(zhí)行某個(gè)case分支的代碼段的話 可以使用 case 變量 in 條件1|條件2) 代碼段 ;; *)代碼塊 ;; esac

    shell其他知識(shí)

    shell函數(shù)

    函數(shù)的優(yōu)點(diǎn)就是代碼模塊化。函數(shù)也就是方法。

    語法:

    # 語法一 函數(shù)名 () {代碼塊return N }# 語法二 function 函數(shù)名 {代碼塊return N }

    上面的僅僅是定義函數(shù),如果想調(diào)用的話 直接寫函數(shù)名。比如

    start () {echo "start ....... [ok]" }# 啟動(dòng)函數(shù) start

    /etc/init.d/functions 目錄下有很多的函數(shù)


    正則表達(dá)式

    它是文本模式匹配,作用就是用它提供的特殊字符生成一個(gè)公式,用這個(gè)公式從海量的數(shù)據(jù)中篩選出我需要的數(shù)據(jù)。

    shell也支撐正則表達(dá)式,但并不是所有命令都支撐,常見的支撐的命令有:grep sed awk

    特殊字符

    定位符說明
    ^錨定一個(gè)開頭字符
    &錨定一個(gè)結(jié)尾字符

    如果兩個(gè)符號(hào)一起使用就是精確匹配,如果只是使用其中一個(gè)是模糊匹配。

    # 假如現(xiàn)在有一個(gè)文件 file.txt 中存放了很多字符串 # 查詢以a字符串開頭 grep命令默認(rèn)是不支持正則表達(dá)式的,需要加上-e屬性才能支撐 [root@VM-8-7-centos shell_02]# grep -e "^a" file.txt# grep -e 等于 egrep # 查詢以c結(jié)尾的字符串 [root@VM-8-7-centos shell_02]# egrep "c&" file.txt# 查詢以a開頭c結(jié)尾的字符串 下面的寫法是精確匹配 最后的結(jié)果只能查詢出來ac字符串 [root@VM-8-7-centos shell_02]# egrep "^ac&" file.txt 匹配符說明
    .匹配一個(gè)除回車外的任意字符
    ()字符串分組 , 使用場(chǎng)景比如以a或b字符開頭
    []定義字符串,匹配括號(hào)中的一個(gè)字符
    [^]正好和上面相反,表示除了括號(hào)中的字符不匹配,其他的字符都匹配
    \轉(zhuǎn)義
    |
    # 匹配以a開頭c結(jié)尾的字符串,這兩個(gè)字符之間可以有一個(gè)任意字符 但僅僅只能有一個(gè) [root@VM-8-7-centos shell_02]# egrep "^a.c&" file.txt# 我想以a或者b開頭 c結(jié)尾 [root@VM-8-7-centos shell_02]# egrep "^(a|b)c&" file.txt# 我想以a開頭c結(jié)尾 中間有任意一個(gè)數(shù)字 [root@VM-8-7-centos shell_02]# egrep "^a[0-9]c&" file.txt# 我想以a開頭c結(jié)尾 中間有任意一個(gè)數(shù)字 [root@VM-8-7-centos shell_02]# egrep "^a[0-9]c&" file.txt# 假如我就是想查詢 "a*b" 字符串 但是*在正則中又有特殊含義 所以就需要轉(zhuǎn)義了 [root@VM-8-7-centos shell_02]# egrep "^a\*c&" file.txt 限定符說明
    *某個(gè)字符之后加*表示改字符可以出現(xiàn)[o,+∞]次
    某個(gè)字符出現(xiàn)[0,1]次
    +某個(gè)字符出現(xiàn)[1,+∞]次
    {n,m}某個(gè)字符出現(xiàn)[n,m]次
    {m}正好出現(xiàn)m次
    # 我想查詢以a開頭c結(jié)尾 中間有任意多個(gè)數(shù)字 [root@VM-8-7-centos shell_02]# egrep "^a[0-9]*c&"

    posix特殊字符

    [:alnum:] 這個(gè)是一個(gè)字符串,使用是需要 [[]] ,最外面的方括號(hào)表示一個(gè)字符,里面的就是一個(gè)posix特殊字符。

    # 我想查詢以a開頭c結(jié)尾 中間可以有一個(gè)任意字母字符 [root@VM-8-7-centos shell_02]# egrep "^a[[:alnum:]]*c&"

    對(duì)文件的操作

    對(duì)文件進(jìn)行增刪改的操作,使用vim的確也可以實(shí)現(xiàn),但vim命令是交互式的,shell腳本不支持交互式去調(diào)用文件,這就需要使用到sed命令,它可以直接對(duì)文本進(jìn)行操作而不需要交互

    sed命令,是linux中提供的一個(gè)行編輯器命令,使用者只能在命令行輸入編輯命令、指定文件名,然后在屏幕上查看輸出,它和文本編輯器的區(qū)別是文本編輯器是針對(duì)文本,而行編輯器針對(duì)的是文件中的某一行,它一次處理文件中的某一行

    如果一個(gè)文件幾百M(fèi)B,直接用vim進(jìn)行打開會(huì)讀取全都文件的內(nèi)容,比較暫用文件內(nèi)存,所以對(duì)于大文件可以使用行編輯器。

    sed數(shù)據(jù)處理原理

    首先讀取文件中的一行數(shù)據(jù)到內(nèi)存中,然后在內(nèi)存中進(jìn)行處理,然后輸出到電腦屏幕。所以它默認(rèn)不會(huì)修改源文件,修改的只是讀取到內(nèi)存中的數(shù)據(jù)。如果想修改文件中的內(nèi)容就需要加一個(gè)命令選項(xiàng)

    語法:

    sed [options] '{command}[flags]' [文件名] # 其中{} 是必填項(xiàng)

    各個(gè)位置能夠填寫的參數(shù)是

    #options選項(xiàng) -e script 將腳本中指定的命令添加到處理輸入時(shí)執(zhí)行的命令中 多條件,一行中要有多個(gè)操作 -f script 將文件中指定的命令添加到處理輸入時(shí)執(zhí)行的命令中 -n 抑制自動(dòng)輸出 -i 編輯文件內(nèi)容 -i.bak 修改時(shí)同時(shí)創(chuàng)建.bak備份文件。 -r 使用擴(kuò)展的正則表達(dá)式 ! 取反 (跟在模式條件后與shell有所區(qū)別)#command 對(duì)文件干什么 sed常用內(nèi)部命令 a 在匹配后面添加 i 在匹配前面添加 d 刪除 s 查找替換 字符串 c 更改 y 轉(zhuǎn)換 N D P p 打印#flags 數(shù)字 表示新文本替換的模式 g: 表示用新文本替換現(xiàn)有文本的全部實(shí)例 p: 表示打印原始的內(nèi)容 w filename: 將替換的結(jié)果寫入文件

    首先創(chuàng)建一個(gè)文本文件,并輸入一些內(nèi)容

    [root@VM-8-7-centos shell_04]# vim data.txt1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog.

    開始set命令

    # 在每一行后面添加hello字符串 [root@VM-8-7-centos shell_04]# sed 'ahello' data.txt 1 the quick brown fox jumps over the lazy dog. hello 2 the quick brown fox jumps over the lazy dog. hello 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. hello 5 the quick brown fox jumps over the lazy dog. hello# 第一個(gè)字母就表示命令 為了好區(qū)分開可以在命令和要插入的數(shù)據(jù)之間加一個(gè) \ [root@VM-8-7-centos shell_04]# sed 'a\hello' data.txt 1 the quick brown fox jumps over the lazy dog. hello 2 the quick brown fox jumps over the lazy dog. hello 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. hello 5 the quick brown fox jumps over the lazy dog. hello# 還可以在指定的一行后面添加數(shù)據(jù) 比如在第三行添加數(shù)據(jù) 只是在命令前面加一行即可 [root@VM-8-7-centos shell_04]# sed '3a\hello' data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog.# 還可以在一個(gè)范圍中添加數(shù)據(jù) 就比如在2-4行添加數(shù)據(jù) [root@VM-8-7-centos shell_04]# sed '2,4a\hello' data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. hello 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. hello 5 the quick brown fox jumps over the lazy dog.# 上面的幾種都不太適用于生產(chǎn)的環(huán)境,因?yàn)榈綍r(shí)候不可能一行一行的去數(shù) # 有一種匹配模式 可以搜索 特定的一些行進(jìn)行新增 sed '/特定字符串/命令\要新增的字符串' 文件名 [root@VM-8-7-centos shell_04]# sed '/3 the quick/a\hello' data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog.# a 命令是在一行的后面進(jìn)行追加,i是在一行的前面進(jìn)行新增 [root@VM-8-7-centos shell_04]# sed 'i\hello' data.txt hello 1 the quick brown fox jumps over the lazy dog. hello 2 the quick brown fox jumps over the lazy dog. hello 3 the quick brown fox jumps over the lazy dog. hello 4 the quick brown fox jumps over the lazy dog. hello 5 the quick brown fox jumps over the lazy dog. # 還有其他幾個(gè) [root@VM-8-7-centos shell_04]# sed '3i\hello' data.txt # 在第三行插入字符串 [root@VM-8-7-centos shell_04]# sed '2,4\hello' data.txt # 在第2-4行插入字符串 [root@VM-8-7-centos shell_04]# sed '/3 the qu/\hello' data.txt # 在這一個(gè)特定字符串的這一行插入字符串# 刪除第三行 [root@VM-8-7-centos shell_04]# sed '3d' data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog.

    sed命令默認(rèn)不支持正則表達(dá)式,可以加一個(gè)-r的名稱選項(xiàng),比如我想刪除一個(gè)文件中所有# 開頭的注釋以及 空行

    [root@VM-8-7-centos shell_04]# sed -r '/(^#|#|^$)/d' /home/hs/shell/shell_03/while_circulation.sh fun1 () { read -p "username: " USER while [ $USER != "root" ]doecho "賬號(hào)錯(cuò)誤"read -p "username: " USER done } while read idoecho "$i" done < $1#

    上面的這行 sed -r '/(^#|#|^$)/d' /home/hs/shell/shell_03/while_circulation.sh '

    -r 是讓后面支持正則表達(dá)式

    / ... / 這個(gè)是開啟匹配模式

    (^#|#|^$) 這個(gè)表示以#開頭 或者是包含# 或者空行

    d 這個(gè)命令是表示刪除

    最后的是文件名,所以上面一行代表的意思就是刪除腳本中的注釋與空行。

    增加和刪除都已經(jīng)出現(xiàn)了,接下來是修改 命令是 s 和 c

    # 修改有兩種 替換與修改 首先是替換 將dog替換為cat [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog. # 命令格式是 sed 's/原字符串/新字符串/' 文件名 [root@VM-8-7-centos shell_04]# sed 's/dog/cat/' data.txt 1 the quick brown fox jumps over the lazy cat. 2 the quick brown fox jumps over the lazy cat. 3 the quick brown fox jumps over the lazy cat. 4 the quick brown fox jumps over the lazy cat. 5 the quick brown fox jumps over the lazy cat. [root@VM-8-7-centos shell_04]# sed '3s/dog/cat/' data.txt 特定行 [root@VM-8-7-centos shell_04]# sed '2,4s/dog/cat/' data.txt 一個(gè)范圍的行數(shù) [root@VM-8-7-centos shell_04]# sed '/3 the quick/s/dog/cat/' data.txt 匹配模式# 修改 命令為c 將每一行的內(nèi)容修改為 [root@VM-8-7-centos shell_04]# sed 'c\hello world' data.txt hello world hello world hello world hello world hello world # 有一個(gè)小細(xì)節(jié) 如果是想修改2-4行 使用其他的方式 它就會(huì)把2-4行刪除 然后重新新增一行 [root@VM-8-7-centos shell_04]# sed '2,4c\hello world' data.txt 1 the quick brown fox jumps over the lazy dog. hello world 5 the quick brown fox jumps over the lazy dog.

    還有轉(zhuǎn)換,將一個(gè)字母轉(zhuǎn)換為另一個(gè)字母

    [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog. # 將a轉(zhuǎn)換為A b轉(zhuǎn)換為B 這里注意 位置是一一對(duì)應(yīng)的 中間字符串第一個(gè)只會(huì)轉(zhuǎn)換為后面的字符串的第一個(gè) [root@VM-8-7-centos shell_04]# sed 'y/abcde/ABCDE/' data.txt 1 thE quiCk Brown fox jumps ovEr thE lAzy Dog. 2 thE quiCk Brown fox jumps ovEr thE lAzy Dog. 3 thE quiCk Brown fox jumps ovEr thE lAzy Dog. 4 thE quiCk Brown fox jumps ovEr thE lAzy Dog. 5 thE quiCk Brown fox jumps ovEr thE lAzy Dog.

    將文件的內(nèi)容打印到屏幕

    [root@VM-8-7-centos shell_04]# sed 'p' data.txt 1 the quick brown fox jumps over the lazy dog. 1 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 2 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. 3 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 4 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog. 5 the quick brown fox jumps over the lazy dog.

    這里會(huì)出現(xiàn)重復(fù)的,因?yàn)檫@里將文件的內(nèi)容打印到屏幕 還會(huì)將內(nèi)存的數(shù)據(jù)打印到屏幕。


    對(duì)文件的補(bǔ)充

    sed命令格式:sed [命令選項(xiàng)] '{命令}[flag標(biāo)志]' [文件名]

    各個(gè)位置能夠填寫的參數(shù)是

    #options選項(xiàng) -e script 將腳本中指定的命令添加到處理輸入時(shí)執(zhí)行的命令中 多條件,一行中要有多個(gè)操作 -f script 將文件中指定的命令添加到處理輸入時(shí)執(zhí)行的命令中 -n 抑制自動(dòng)輸出 -i 編輯文件內(nèi)容 -i.bak 修改時(shí)同時(shí)創(chuàng)建.bak備份文件。 -r 使用擴(kuò)展的正則表達(dá)式 ! 取反 (跟在模式條件后與shell有所區(qū)別)#command 對(duì)文件干什么 sed常用內(nèi)部命令 a 在匹配后面添加 i 在匹配前面添加 d 刪除 s 查找替換 字符串 c 更改 y 轉(zhuǎn)換 N D P p 打印#flags 數(shù)字 表示新文本替換的模式 g: 表示用新文本替換現(xiàn)有文本的全部實(shí)例 p: 表示打印原始的內(nèi)容 w filename: 將替換的結(jié)果寫入文件

    上面主要是將了命令相關(guān)的知識(shí) 還講了命令選項(xiàng)-r 讓后面支持正則表達(dá)式 接下來主要是將flag標(biāo)志 這其實(shí)就是對(duì)命令的一個(gè)補(bǔ)充 還有一些其他的命令選項(xiàng)。

    假如我現(xiàn)在將data.txt文件的內(nèi)容改一下 結(jié)尾再加一個(gè)dog

    1 the quick brown fox jumps over the lazy dog.dog 2 the quick brown fox jumps over the lazy dog.dog 3 the quick brown fox jumps over the lazy dog.dog 4 the quick brown fox jumps over the lazy dog.dog 5 the quick brown fox jumps over the lazy dog.dog

    接下來對(duì)這個(gè)文件進(jìn)行操作

    現(xiàn)在繼續(xù)將dog單詞替換為cat

    [root@VM-8-7-centos shell_04]# sed 's/dog/cat/' data.txt 1 the quick brown fox jumps over the lazy cat.dog 2 the quick brown fox jumps over the lazy cat.dog 3 the quick brown fox jumps over the lazy cat.dog 4 the quick brown fox jumps over the lazy cat.dog 5 the quick brown fox jumps over the lazy cat.dog

    這就會(huì)出現(xiàn)僅僅只是替換了第一個(gè)dog單詞改為了cat。如果我想將讀取到內(nèi)充中的這一行中所有的dog都替換為cat如何實(shí)現(xiàn)?如果我僅僅替換第二次出現(xiàn)的dog又如何實(shí)現(xiàn)?這就需要使用到flag標(biāo)志了。

    # 直接在標(biāo)志位寫一個(gè)數(shù)字2即可實(shí)現(xiàn)將第二個(gè)dog替換為cat [root@VM-8-7-centos shell_04]# sed 's/dog/cat/2' data.txt 1 the quick brown fox jumps over the lazy dog.cat 2 the quick brown fox jumps over the lazy dog.cat 3 the quick brown fox jumps over the lazy dog.cat 4 the quick brown fox jumps over the lazy dog.cat 5 the quick brown fox jumps over the lazy dog.cat# 如果在標(biāo)志位使用g 這是將一行中所有的dog替換為cat [root@VM-8-7-centos shell_04]# sed 's/dog/cat/g' data.txt 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat

    還可以打印輸出 比如打印輸出第三行

    [root@VM-8-7-centos shell_04]# sed '3s/dog/cat/p' data.txt 1 the quick brown fox jumps over the lazy dog.dog 2 the quick brown fox jumps over the lazy dog.dog 3 the quick brown fox jumps over the lazy cat.dog 3 the quick brown fox jumps over the lazy cat.dog 4 the quick brown fox jumps over the lazy dog.dog 5 the quick brown fox jumps over the lazy dog.dog

    現(xiàn)在所有的修改都是針對(duì)內(nèi)存來進(jìn)行操作的,修改數(shù)據(jù)后真正的文件內(nèi)容不會(huì)改變 如果想修改的內(nèi)容讓文件改變就在標(biāo)志位寫上 w

    # 標(biāo)志位 后面還需要寫一個(gè)文件名 表示將修改后的內(nèi)容保存至哪一個(gè)文件 [root@VM-8-7-centos shell_04]# sed 's/dog/cat/w data_copy.txt' data.txt 1 the quick brown fox jumps over the lazy cat.dog 2 the quick brown fox jumps over the lazy cat.dog 3 the quick brown fox jumps over the lazy cat.dog 4 the quick brown fox jumps over the lazy cat.dog 5 the quick brown fox jumps over the lazy cat.dog [root@VM-8-7-centos shell_04]# ls data_copy.txt data.txt [root@VM-8-7-centos shell_04]# cat data_copy.txt 1 the quick brown fox jumps over the lazy cat.dog 2 the quick brown fox jumps over the lazy cat.dog 3 the quick brown fox jumps over the lazy cat.dog 4 the quick brown fox jumps over the lazy cat.dog 5 the quick brown fox jumps over the lazy cat.dog# 如果不寫文件名是會(huì)報(bào)錯(cuò)的 [root@VM-8-7-centos shell_04]# sed 's/dog/cat/w' data.txt sed: couldn't open file : No such file or directory

    上面是修改了第一個(gè)dog單詞,如果我想修改一行中所有的dog單詞 然后將修改的結(jié)果進(jìn)行保存至另一個(gè)文件中,問題就是標(biāo)志位的命令可不可使用多個(gè),答案是可以的

    [root@VM-8-7-centos shell_04]# sed 's/dog/cat/gw aa.txt' data.txt 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat [root@VM-8-7-centos shell_04]# ls aa.txt data.txt [root@VM-8-7-centos shell_04]# cat aa.txt 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat

    我想能不能修改后的內(nèi)容保存在原來的文件中,試了一下,結(jié)果導(dǎo)致原文件中的內(nèi)容都沒有了

    [root@VM-8-7-centos shell_04]# sed 's/dog/cat/w data.txt' data.txt

    接下來是講命令選項(xiàng) ,命令選項(xiàng)是對(duì)sed命令的補(bǔ)充

    首先是僅僅打印我修改了的數(shù)據(jù),內(nèi)存中讀入的數(shù)據(jù)不打印 使用-n

    [root@VM-8-7-centos shell_04]# sed -n '3s/dog/cat/p' data.txt 3 the quick brown fox jumps over the lazy cat.dog [root@VM-8-7-centos shell_04]# sed -n '3s/dog/cat/' data.txt [root@VM-8-7-centos shell_04]# # 加上-n就可以僅僅顯示我們要打印的數(shù)據(jù),如果沒有在命令或者flag標(biāo)志中選擇p打印的話 -n最后是沒有任何數(shù)據(jù)顯示的

    還可以執(zhí)行多個(gè)命令,就比如我要將brown單詞改為green dog單詞改為cat 像這種需要執(zhí)行多個(gè)命令的就需要使用 -e 中間用; 隔開

    [root@VM-8-7-centos shell_04]# sed -e 's/brown/green/;s/dog/cat/g' data.txt 1 the quick green fox jumps over the lazy cat.cat 2 the quick green fox jumps over the lazy cat.cat 3 the quick green fox jumps over the lazy cat.cat 4 the quick green fox jumps over the lazy cat.cat 5 the quick green fox jumps over the lazy cat.cat

    還可以將命令寫入到文件中,執(zhí)行時(shí)直接讀取文件中的命令來執(zhí)行 需要使用-f

    # 首先創(chuàng)建一個(gè)文件 [root@VM-8-7-centos shell_04]# vim command.txt# 文件內(nèi)容如下 還是上面的將brown單詞改為green dog單詞改為cat 因?yàn)檫@里命令沒有寫在一行 所以中間就不用分號(hào)隔開 s/brown/grent/ s/dog/cat/g# 然后在執(zhí)行 command.txt為命令文件 data.txt為原數(shù)據(jù)文件 [root@VM-8-7-centos shell_04]# sed -f command.txt data.txt 1 the quick grent fox jumps over the lazy cat.cat 2 the quick grent fox jumps over the lazy cat.cat 3 the quick grent fox jumps over the lazy cat.cat 4 the quick grent fox jumps over the lazy cat.cat 5 the quick grent fox jumps over the lazy cat.cat

    修改源文件,上面使用命令flag標(biāo)志w 只是將打印內(nèi)容寫入到另一個(gè)文件,現(xiàn)在是對(duì)源文件進(jìn)行修改。

    [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy dog.dog 2 the quick brown fox jumps over the lazy dog.dog 3 the quick brown fox jumps over the lazy dog.dog 4 the quick brown fox jumps over the lazy dog.dog 5 the quick brown fox jumps over the lazy dog.dog [root@VM-8-7-centos shell_04]# sed -i 's/dog/cat/g' data.txt # 將所有的dog修改為cat 后屏幕是沒有輸出 但是再查看原文件內(nèi)容已經(jīng)發(fā)生了改變 [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat# 在日常中 修改源文件其實(shí)是很危險(xiǎn)的操作 因?yàn)檫@是不可逆的 可以使用-i.xxx 先對(duì)原文件進(jìn)行備份,然后再對(duì)原文件進(jìn)行修改 # 現(xiàn)在的data.txt文件內(nèi)容 [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat # 現(xiàn)在進(jìn)行修改操作 [root@VM-8-7-centos shell_04]# sed -i.0905 's/cat/dog/g' data.txt # 這個(gè)時(shí)候就會(huì)自動(dòng)創(chuàng)建一個(gè)data.txt.0905文件 [root@VM-8-7-centos shell_04]# ls command.txt data.txt data.txt.0905 # 修改后的data.txt文件 [root@VM-8-7-centos shell_04]# cat data.txt 1 the quick brown fox jumps over the lazy dog.dog 2 the quick brown fox jumps over the lazy dog.dog 3 the quick brown fox jumps over the lazy dog.dog 4 the quick brown fox jumps over the lazy dog.dog 5 the quick brown fox jumps over the lazy dog.dog # 修改前進(jìn)行備份的原文件 [root@VM-8-7-centos shell_04]# cat data.txt.0905 1 the quick brown fox jumps over the lazy cat.cat 2 the quick brown fox jumps over the lazy cat.cat 3 the quick brown fox jumps over the lazy cat.cat 4 the quick brown fox jumps over the lazy cat.cat 5 the quick brown fox jumps over the lazy cat.cat

    sed命令小技巧

    統(tǒng)計(jì)data.txt文件有多少行

    [root@VM-8-7-centos shell_04]# sed -n '$=' data.txt 5

    對(duì)輸出流處理

    awk命令可以幫助我們從輸出流中把我們想要的數(shù)據(jù)找出來并對(duì)這些數(shù)據(jù)進(jìn)行處理,awk也是一個(gè)行編輯器命令,可以截取某一行中某一列的內(nèi)容并對(duì)這些內(nèi)容進(jìn)行處理、運(yùn)算、輸出。

    awk工作方式是讀取數(shù)據(jù),將每一行數(shù)據(jù)視為一條記錄, 每條記錄以分隔符分為若干個(gè)字段 行的分隔符為回車 字段的分割為一個(gè)或多個(gè)空格

    就比如求內(nèi)存的使用率,所有的內(nèi)存數(shù)以及已使用的內(nèi)存都在一行的中,如果需要將我們想要的數(shù)據(jù)檢索出來并進(jìn)行處理就可以使用awk命令

    [root@VM-8-7-centos ~]# freetotal used free shared buff/cache available Mem: 1882008 458880 94056 592 1329072 1226400 Swap: 0 0 0

    語法:

    awk [option命令選項(xiàng)] '[BEGIN]{program}[END]' [fileName]

    命令選項(xiàng)為:

    • -F fs 一行中各個(gè)字段的列分隔符 默認(rèn)是空格 如果是其他的就需要使用該命令選項(xiàng)來指定分隔符
    • -f file 指定讀取程序的文件名
    • -v var=value awk使用的變量與值

    awk的命令program必須放在兩個(gè)大括號(hào)中,并且必須用單引號(hào)將大括號(hào)引起來

    awk的運(yùn)行優(yōu)先級(jí):

    • BEGIN: 在開始處理數(shù)據(jù)流之前執(zhí)行,可選項(xiàng)
    • program: 如何處理數(shù)據(jù)流,必選項(xiàng)
    • END: 處理完數(shù)據(jù)流后執(zhí)行,可選項(xiàng)

    awk命令基本用法

    awk的基本用法就是數(shù)據(jù)的提取功能,能夠從一行中提取某一個(gè)字段

    首先創(chuàng)建一個(gè)文本文件

    [root@VM-8-7-centos shell_04]# vim awk_data.txt1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog

    awk命令對(duì)列的提取

    字段相關(guān)內(nèi)置變量

    $0 表示整行文本

    $1 表示文本行中的第一個(gè)數(shù)據(jù)字段

    $2 表示文本行中的第二個(gè)數(shù)據(jù)字段

    $N 表示文本行中的第N個(gè)數(shù)據(jù)字段

    $NF 表示文本行中的最后一個(gè)數(shù)據(jù)字段

    # 提取整行內(nèi)容 awk的打印輸出命令是print [root@VM-8-7-centos shell_04]# awk '{print $0}' awk_data.txt 1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog# 提取每行第三個(gè)字段的內(nèi)容 [root@VM-8-7-centos shell_04]# awk '{print $3}' awk_data.txt quick quick quick quick quick# 還可以打印多個(gè)字段 直接在{} 中寫多個(gè)$ 即可 中間用逗號(hào)分割 [root@VM-8-7-centos shell_04]# awk '{print $1,$3,$5}' awk_data.txt 1 quick fox 2 quick fox 3 quick fox 4 quick fox 5 quick fox

    對(duì)行的提取

    上面會(huì)了對(duì)列的提取,如果我想提取某一行 可以使用NR來指定,或者開啟匹配模式

    # 比如 提取第三行的整行內(nèi)容 [root@VM-8-7-centos shell_04]# awk 'NR==3{print $0}' awk_data.txt 3 the quick brown fox jumps over the lazy cat . dog[root@VM-8-7-centos shell_04]# awk '/2 the/{print $0}' awk_data.txt 2 the quick brown fox jumps over the lazy cat . dog

    如果列的分隔符不是空格的情形下

    上面都是對(duì)awk_data.txt文件進(jìn)行操作,這是一個(gè)標(biāo)準(zhǔn)的文件,字段與字段之間采用的是空格分割的,那如果采用的其他符號(hào)進(jìn)行分隔符就需要在option命令選項(xiàng)使用-F

    # 比如這個(gè)文件,字段與字段之間采用的冒號(hào)分割 [root@VM-8-7-centos shell_04]# cat /etc/passwd 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 sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt ......# 使用-F 指定字段分隔符 [root@VM-8-7-centos shell_04]# awk -F ":" '{print $1}' /etc/passwd root bin daemon adm lp sync shutdown halt ......# 還可以將 awk -F ":" 寫成 awk -F:

    改變輸出后的字段分割符

    打印的多個(gè)字段默認(rèn)采用的是空格分割,還可以改變, 格式為:awk '{print $1 "雙引號(hào)中寫自定義的分隔符" $2}' 文件名

    # 默認(rèn)輸出在屏幕后的字段是采用的空格分割 [root@VM-8-7-centos shell_04]# awk '{print $1,$3,$5}' awk_data.txt 1 quick fox 2 quick fox 3 quick fox 4 quick fox 5 quick fox# 改變分隔符后的輸出 [root@VM-8-7-centos shell_04]# awk '{print $1 "--" $3 "--" $5}' awk_data.txt 1--quick--fox 2--quick--fox 3--quick--fox 4--quick--fox 5--quick--fox

    其實(shí)就是打印字符串,雙引號(hào)引起來的就是字符串,如果沒有引起來的就是變量

    awk的三個(gè)優(yōu)先級(jí)

    BEGIN的優(yōu)先級(jí)最高 最先執(zhí)行 它是在從輸出流中讀取數(shù)據(jù)之前進(jìn)行的操作 , 它不依賴于輸出流 所以僅僅使用BEGIN允許最后沒有文件名

    END 的優(yōu)先級(jí)最低 最后執(zhí)行 它是在輸出流中操作數(shù)據(jù)之后執(zhí)行

    [root@VM-8-7-centos shell_04]# awk 'BEGIN{print "begin...."}{print $0}END{print "end..."}' awk_data.txt begin.... 1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog end...# 不需要數(shù)據(jù)源也可以輸出 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print "begin...."}' begin....# 沒有提供數(shù)據(jù)源 所以無法輸出 [root@VM-8-7-centos shell_04]# awk '{print "test...."}'

    awk命令高級(jí)用法

    awk是一門語言,可以定義變量,還可以定義數(shù)組,還可以進(jìn)行運(yùn)算,環(huán)境變量,流程控制。

    定義變量,案例使用查看內(nèi)存的使用率,如下:

    # 第一個(gè)是總內(nèi)存 第二個(gè)是剩余內(nèi)存 [root@VM-8-7-centos shell_04]# head -2 /proc/meminfo MemTotal: 1882008 kB MemFree: 123520 kB[root@VM-8-7-centos shell_04]# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)/t*100 "%"}' 93.4561%# 定義變量還可以這樣使用 [root@VM-8-7-centos shell_04]# awk 'BEGIN{name="胡尚";print name}' 胡尚

    定義數(shù)組

    [root@VM-8-7-centos shell_04]# awk 'BEGIN{array[1]="hushang";array[2]="21";print array[1],array[2]}' hushang 21

    awk運(yùn)算

    • 賦值運(yùn)算 =
    • 比較運(yùn)算 > >= == != <= <
    • 數(shù)學(xué)運(yùn)算 + - * / % ++ – **
    • 邏輯運(yùn)算 && || !
    • 匹配運(yùn)算 ~ !~ == !=
    # 賦值運(yùn)算就不說了 上面定義變量就是賦值運(yùn)算# 比較運(yùn)算。如果比較的是字符串則按ascii編碼順序表比較。如果結(jié)果返回為真則用1表示,如果返回為假則用0表示 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print "a" >= "b"}' 0# 數(shù)學(xué)運(yùn)算 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print 100+20}' 120 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print 100/3}' 33.3333 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print 2**5}' # ----> 2^5 32 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print 10%3}' 1# 邏輯運(yùn)算 還是一樣 如果結(jié)果返回為真則用1表示,如果返回為假則用0表示 [root@VM-8-7-centos shell_04]# awk 'BEGIN{print "a" <= "b" && "b" >= "c"}' 0

    下面是匹配運(yùn)算,也是用的比較多的

    # passwd文件如下 [root@VM-8-7-centos shell_04]# cat /etc/passwd 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 sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt ...# 使用 == 來進(jìn)行精確匹配 只輸出第一個(gè)字段為root的一行 [root@VM-8-7-centos shell_04]# awk -F ":" '$1=="root"{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash# 還可以使用模糊匹配 只要第一個(gè)字段中包含ro的都會(huì)被打印出來 [root@VM-8-7-centos shell_04]# awk '$1 ~ "ro"{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin chrony:x:997:995::/var/lib/chrony:/sbin/nologin

    環(huán)境變量

    變量描述
    FIELDWIDTHS以空格分隔的數(shù)字列表,用空格定義每個(gè)數(shù)據(jù)字段的精確寬度
    FS輸入字段分隔符號(hào) 數(shù)據(jù)源的字段分隔符 -F
    OFS輸出字段分隔符號(hào)
    RS輸入記錄分隔符
    ORS輸出記錄分隔符號(hào)
    # 首先是第一個(gè)環(huán)境變量 第一行是先輸出/etc/passwd文件的第一行內(nèi)容 [root@VM-8-7-centos shell_04]# awk 'NR==1{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash # 使用FIELDWIDTHS變量后的結(jié)果 [root@VM-8-7-centos shell_04]# awk 'BEGIN{FIELDWIDTHS="5 2 8"}NR==1{print $1,$2,$3}' /etc/passwd root: x: 0:0:root# FS 和 OFS 兩個(gè)環(huán)境變量 [root@VM-8-7-centos shell_04]# awk 'NR==1{print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash [root@VM-8-7-centos shell_04]# awk 'BEGIN{FS=":"}NR==1{print $1,$3,$5}' /etc/passwd root 0 root [root@VM-8-7-centos shell_04]# awk 'BEGIN{FS=":";OFS="-"}NR==1{print $1,$3,$5}' /etc/passwd root-0-root# 剩下兩個(gè)就是一行 輸入的默認(rèn)分隔符與輸出到屏幕的行分隔符。

    awk流程控制與循環(huán)

    if語句

    # 首先是查看文件 [root@VM-8-7-centos shell_04]# cat awk_data.txt 1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog# 打印第一個(gè)字段小于3的數(shù)據(jù) [root@VM-8-7-centos shell_04]# awk '{if($0 < 3)print $0}' awk_data.txt 1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog # 上面是寫在一行中 還可以通過shift+enter 寫在多行 [root@VM-8-7-centos shell_04]# awk '{ > if($1<3) > print $0 > }' awk_data.txt 1 the quick brown fox jumps over the lazy cat . dog 2 the quick brown fox jumps over the lazy cat . dog# 但是不理解為什么下面 > 3 的條件竟然將第三行輸出了 [root@VM-8-7-centos shell_04]# awk '{if($0 > 3)print $0}' awk_data.txt 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog [root@VM-8-7-centos shell_04]# awk '{if($0 >= 3)print $0}' awk_data.txt 3 the quick brown fox jumps over the lazy cat . dog 4 the quick brown fox jumps over the lazy cat . dog 5 the quick brown fox jumps over the lazy cat . dog

    if…else…語句

    [root@VM-8-7-centos shell_04]# awk '{ > if($1<3) > print $1*2 > else > print $1/2 > '} awk_data.txt 2 4 1.5 2 2.5

    for循環(huán)

    首先創(chuàng)建一個(gè)文件,保存幾個(gè)數(shù)字

    [root@VM-8-7-centos shell_04]# vim number.txt60 50 100 150 30 10 70 100 40

    求和

    # 首先使用-v命令選項(xiàng)定義一個(gè)變量 然后進(jìn)行循環(huán) 最后使用end進(jìn)行輸出 [root@VM-8-7-centos shell_04]# awk -v "sum=0" '{for(i=1;i<4;i++){sum+=$i}}END{print sum}' number.txt 610# 在begin中定義變量也可以 [root@VM-8-7-centos shell_04]# awk 'BEGIN{sum=0}{for(i=1;i<4;i++){sum+=$i}}END{print sum}' number.txt 610# 使用多行的格式 [root@VM-8-7-centos shell_04]# awk -v "sum=0" '{ > for(i=1;i<4;i++){ > sum+=$i > }}END{print sum}' number.txt 610

    while循環(huán)

    使用while循環(huán) 輸出每行的幾個(gè)字段的和

    [root@VM-8-7-centos shell_04]# cat number.txt 60 50 100 150 30 10 70 100 40[root@VM-8-7-centos shell_04]# awk '{ > i=1 > sum=0 > while(i<4){ > sum+=$i > i++ > } > print sum}' number.txt 210 190 210

    還有一個(gè)do…while格式。先執(zhí)行循環(huán)在進(jìn)行判斷

    [root@VM-8-7-centos shell_04]# awk '{ > sum=0 > i=1 > do{ > sum+=$i > i++ > }while(i<4) > print sum}' number.txt 210 190 210

    循環(huán)控制語句

    break

    awk小技巧

    # 打印行數(shù) [root@VM-8-7-centos shell_04]# awk 'END{print NR}' number.txt 3# 打印最后一行內(nèi)容 [root@VM-8-7-centos shell_04]# awk 'END{print $0}' number.txt 70 100 40# 打印列數(shù) [root@VM-8-7-centos shell_04]# awk 'END{print NF}' number.txt 3

    腳本案例


    監(jiān)控一個(gè)主機(jī)的存活狀態(tài)

    監(jiān)控方法采用ping 使用的是icmp協(xié)議。如果能ping通則表示主機(jī)存活 如果ping不通則主機(jī)死亡

    關(guān)于該知識(shí)點(diǎn)的一些問題

  • 關(guān)于禁ping 防止DDOS攻擊

    這里主機(jī)如果是禁ping 禁的是陌生人 。 禁止所有但是允許你自己的ip進(jìn)行ping的操作

  • 網(wǎng)絡(luò)有延遲,可能因?yàn)榫W(wǎng)絡(luò)的原因產(chǎn)生假報(bào)警問題,

    需要設(shè)置ping的報(bào)警閥值,假如三次全部失敗就報(bào)警 主機(jī)down

  • ping的頻率

    1-5秒ping一次都可以 但是不要毫秒級(jí)單位去ping

  • #!/usr/bin/bash # Author: hushang # Cleared Time: 2021-09-07 19:56 # Script Description: 監(jiān)控目標(biāo)主機(jī)存活狀態(tài)for ((i=1;i<4;i++));do # 測(cè)試代碼 -c1 表示就發(fā)生一次ping 不管能否ping通都不輸出結(jié)果 然后定義變量if ping -c1 $1 &>/dev/null;thenexport ping_status"$i"=1elseexport ping_status"$i"=0fi# 時(shí)間間隔 1秒1次sleep 1 done# 3次都ping成功才算成功 if [ $ping_status1 -eq $ping_status2 ] && [ $ping_status2 -eq $ping_status3 ] && [ $ping_status1 -eq 0 ];thenecho "$1 is down" elseecho "$1 is up" fi# 撤銷上面定義的全局變量 unset ping_status1 unset ping_status2 unset ping_status3

    監(jiān)控端口存活狀態(tài)

    比較常見的監(jiān)控方法是:

    • 通過systemctl 或 service 命令來查看服務(wù)啟動(dòng)狀態(tài)
    • 通過lsof命令 查看端口是否存在
    • 通過ps命令 查看進(jìn)程

    上面這三種都有可能出現(xiàn) 服務(wù)down了上述的一些東西還在 或者是 壓力過大 服務(wù)無法響應(yīng)

    這里推薦使用 telnet命令測(cè)試端口是否有響應(yīng)

    如果沒有該命令 那就安裝一下

    # 安裝命令 yum -y install telnet# 測(cè)試一下連接當(dāng)前服務(wù)器的22號(hào)端口 [root@VM-8-7-centos shell_05]# telnet 82.156.9.191 22 Trying 82.156.9.191... Connected to 82.156.9.191. Escape character is '^]'. SSH-2.0-OpenSSH_7.4 # 然后輸入quit退出 # 如果能夠出現(xiàn) '^]' 符號(hào)就表示該端口是開放的 如果端口沒有開放就會(huì)提示connection # 這里有個(gè)小問題 如果我測(cè)試一個(gè)沒有開放的端口 就會(huì)一直等待 不會(huì)有提示信息輸出 可是視頻教程有一個(gè)連接超時(shí)的提示# 該命令的位置 [root@VM-8-7-centos shell_05]# which telnet /usr/bin/telnet

    補(bǔ)充知識(shí)點(diǎn)——?jiǎng)?chuàng)建臨時(shí)文件

    mktemp 文件名.XXXXXX # 可以有多個(gè)X 但至少要有三個(gè)# 現(xiàn)有的文件 [root@VM-8-7-centos shell_05]# ls host_status.sh port_status.sh # 創(chuàng)建一個(gè)臨時(shí)文件 [root@VM-8-7-centos shell_05]# mktemp test.XXX test.uL5 # 創(chuàng)建后就會(huì)看到多了一個(gè)文件 [root@VM-8-7-centos shell_05]# ls host_status.sh port_status.sh test.uL5 # 再創(chuàng)建一次 [root@VM-8-7-centos shell_05]# mktemp test.XXXXXXX test.pikvvR9 [root@VM-8-7-centos shell_05]# ls host_status.sh port_status.sh test.pikvvR9 test.uL5 # 后面寫幾個(gè)X 就會(huì)隨機(jī)生成幾位# 還可以創(chuàng)建臨時(shí)文件夾, 使用-d命令選項(xiàng) mktemp -d test.XXXXXXX

    腳本如下:

    #!/usr/bin/bash # Author: hushang # Created Time: 2021-09-08 12:45 # Script Description: 監(jiān)控一個(gè)主機(jī)的端口port_status () {# 首先判斷一下/usr/bin/telnet這個(gè)可執(zhí)行文件是否存在 if [ ! -f /usr/bin/telnet ];thenecho "not fount command : telnet"exit 1 fi# 創(chuàng)建一個(gè)臨時(shí)文件 用來保存執(zhí)行telnet命令后的輸出內(nèi)容 TEMP_FILE=`mktemp port_status.XXXXX`# 開始測(cè)試端口是否存在 $1代表IP地址 $2代表端口 # 然后將執(zhí)telnet命令 輸出在屏幕的結(jié)果保存在上面創(chuàng)建的一個(gè)臨時(shí)文件 (telnet $1 $2 <<EOF quit EOF ) &> $TEMP_FILE# 使用grep -e 通過檢索這個(gè)臨時(shí)文件 是否包含 ^] 字符 # &>/dev/null 這個(gè)是不需要將檢索臨時(shí)文件的結(jié)果輸出在屏幕上 if egrep "\^]" $TEMP_FILE &>/dev/null;thenecho "$1 $2 is open" elseecho "$1 $2 is close" fi# 將臨時(shí)文件刪除掉 rm -f $TEMP_FILE}# 上面寫的是一個(gè)函數(shù),現(xiàn)在調(diào)用執(zhí)行那個(gè)函數(shù),將兩個(gè)參數(shù)傳給該方法 port_status $1 $2

    監(jiān)控內(nèi)存使用率

    首先是查看內(nèi)存使用情況

    # total總共內(nèi)存 used已使用 free剩余 shered共享內(nèi)存 buff緩沖 [root@VM-8-7-centos ~]# free -mtotal used free shared buff/cache available Mem: 1837 448 122 0 1267 1197 Swap: 0 0 0# 第二個(gè)命令就是: [root@VM-8-7-centos shell_05]# cat /proc/meminfo MemTotal: 1882008 kB MemFree: 126520 kB MemAvailable: 1229092 kB Buffers: 125948 kB Cached: 1048056 kB SwapCached: 0 kB .....

    在這個(gè)里面 內(nèi)存使用的優(yōu)先級(jí)是 free —> cache —> buffer ----> Swap

    當(dāng)used的值不高 free的值不高 buff的值高 這種情況并不是內(nèi)存緊張 ,只是很多東西讀入到內(nèi)存中 沒有清空緩存而已,沒有釋放到free

    當(dāng)used的值高 free的值不高 buff的值也不高 這種情況才是內(nèi)存緊張了

    上面兩種命令隨便選擇一種使用都可以,這里采用第二種

    # 統(tǒng)計(jì)已使用的內(nèi)存占總內(nèi)存的百分比 [root@VM-8-7-centos shell_05]# head -2 /proc/meminfo MemTotal: 1882008 kB MemFree: 126280 kB [root@VM-8-7-centos shell_05]# head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)/t*100"%"}' 93.3059%# 統(tǒng)計(jì)cache的使用率 [root@VM-8-7-centos shell_05]# head -5 /proc/meminfo MemTotal: 1882008 kB MemFree: 126036 kB MemAvailable: 1229168 kB Buffers: 126052 kB Cached: 1048504 kB [root@VM-8-7-centos shell_05]# head -5 /proc/meminfo | awk 'NR==1{t=$2}NR==5{c=$2;print c/t*100"%"}' 55.7171%# 統(tǒng)計(jì)buffer的使用率 [root@VM-8-7-centos shell_05]# head -5 /proc/meminfo | awk 'NR==1{t=$2}NR==4{b=$2;print b/t*100"%"}' 6.69902%

    腳本如下:

    #!/usr/bin/bash # Author: hushang # Created Time: 2021-09-09 13:04 # Script Description: 監(jiān)控內(nèi)存的使用率memory_use(){memory_used=`head -2 /proc/meminfo | awk 'NR==1{t=$2}NR==2{f=$2;print (t-f)/t*100"%"}'`memory_cache=`head -5 /proc/meminfo | awk 'NR==1{t=$2}NR==5{c=$2;print c/t*100"%"}'`memory_buff=`head -5 /proc/meminfo | awk 'NR==1{t=$2}NR==4{b=$2;print b/t*100"%"}'`echo "memory used: $memory_used"echo "memory cache used: $memory_cache"echo "memory buff used: $memory_buff" } memory_use

    使用cpu或內(nèi)存前十的進(jìn)程

    目的:通過監(jiān)控找出一些非法占用內(nèi)存高的進(jìn)程,發(fā)現(xiàn)后停止該進(jìn)程

    監(jiān)控方法:

    ps 或 top 命令 這兩個(gè)命令的區(qū)別是ps的靜態(tài)的命令 顯示上一秒的進(jìn)程情況,而 top 命令是動(dòng)態(tài)的,顯示的數(shù)值會(huì)動(dòng)態(tài)的改變。

    通過對(duì)任務(wù)管理器中的進(jìn)程對(duì)內(nèi)存或cpu的使用情況進(jìn)行整合、排序

    使用上面兩個(gè)命令 其實(shí)顯示的內(nèi)容都差不多

    [root@VM-8-7-centos shell_05]# ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 43612 3672 ? Ss Jun25 10:38 /usr/lib/systemd/systemd --system --deserialize 20 root 2 0.0 0.0 0 0 ? S Jun25 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? S< Jun25 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S Jun25 3:32 [ksoftirqd/0] root 7 0.0 0.0 0 0 ? S Jun25 0:00 [migration/0] root 8 0.0 0.0 0 0 ? S Jun25 0:00 [rcu_bh] ......# 需要用到的也就是RSS 這表示那個(gè)進(jìn)程使用了多少物理內(nèi)存# -n1 表示就打印一次 RES的值也就表示進(jìn)程使用了多少物理內(nèi)存 [root@VM-8-7-centos shell_05]# top -n1 top - 20:24:15 up 76 days, 10:03, 1 user, load average: 0.90, 0.82, 0.63 Tasks: 107 total, 2 running, 105 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1882008 total, 181044 free, 458872 used, 1242092 buff/cache KiB Swap: 0 total, 0 free, 0 used. 1226416 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1047 root 20 0 50088 916 584 R 6.7 0.0 1321:32 rshim 1 root 20 0 43612 3672 2212 S 0.0 0.2 10:39.09 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.31 kthreadd 4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 6 root 20 0 0 0 0 S 0.0 0.0 3:32.11 ksoftirqd/0 7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 # 將top命令打印在屏幕的內(nèi)容輸入至一個(gè)臨時(shí)文件中 [root@VM-8-7-centos shell_05]# top -n1 > temp.txt # 查看該文件 內(nèi)容如下 [root@VM-8-7-centos shell_05]# cat temp.txt top - 20:37:39 up 76 days, 10:16, 1 user, load average: 0.55, 0.44, 0.52 Tasks: 105 total, 2 running, 103 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 1882008 total, 180920 free, 457248 used, 1243840 buff/cache KiB Swap: 0 total, 0 free, 0 used. 1227996 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 11345 rabbitmq 20 0 1827504 84188 4716 S 6.2 4.5 227:39.43 beam.smp 1 root 20 0 43612 3672 2212 S 0.0 0.2 10:39.46 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.31 kthreadd 4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H6 root 20 0 0 0 0 S 0.0 0.0 3:32.19 ksoftirqd/0 7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root 20 0 0 0 0 S 0.0 0.0 10:01.43 rcu_sched 10 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 lru-add-drain 11 root rt 0 0 0 0 S 0.0 0.0 0:14.90 watchdog/0 13 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs 14 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 15 root 20 0 0 0 0 S 0.0 0.0 0:01.22 khungtaskd 16 root 0 -20 0 0 0 S 0.0 0.0 0:00.02 writeback 17 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kintegrityd18 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset 19 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset 20 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset21 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kblockd 22 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 md 23 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 edac-poller 24 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 watchdogd 30 root 20 0 0 0 0 S 0.0 0.0 0:02.99 kswapd0 31 root 25 5 0 0 0 S 0.0 0.0 0:00.00 ksmd 32 root 39 19 0 0 0 S 0.0 0.0 0:06.20 khugepaged 33 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 crypto 41 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kthrotld 43 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kmpath_rdacd 44 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kaluad 45 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kpsmoused 46 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 ipv6_addrconf 59 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 deferwq 98 root 20 0 0 0 0 S 0.0 0.0 0:23.00 kauditd 193 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 iscsi_eh 245 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 ata_sff 251 root 20 0 0 0 0 S 0.0 0.0 0:00.00 scsi_eh_0 252 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 scsi_tmf_0

    但是如果我要?jiǎng)?chuàng)建一個(gè)腳本 所需要使用的內(nèi)容是從第8行開始 那我如何讓內(nèi)容從第八行開始顯示嘞? 這里可以使用tail命令

    # 查看最后4行 如果想從頭開始就將數(shù)字寫我 +n [root@VM-8-7-centos shell_05]# tail -n -5 temp.txt 193 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 iscsi_eh 245 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 ata_sff 251 root 20 0 0 0 0 S 0.0 0.0 0:00.00 scsi_eh_0 252 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 scsi_tmf_0 # 改為+8就表示從第八行開始展示 [root@VM-8-7-centos shell_05]# tail -n +8 temp.txt 11345 rabbitmq 20 0 1827504 84188 4716 S 6.2 4.5 227:39.43 beam.smp 1 root 20 0 43612 3672 2212 S 0.0 0.2 10:39.46 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.31 kthreadd 4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 6 root 20 0 0 0 0 S 0.0 0.0 3:32.19 ksoftirqd/0 7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root 20 0 0 0 0 S 0.0 0.0 10:01.43 rcu_sched 10 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 lru-add-drain 11 root rt 0 0 0 0 S 0.0 0.0 0:14.90 watchdog/0 13 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs 14 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 15 root 20 0 0 0 0 S 0.0 0.0 0:01.22 khungtaskd 16 root 0 -20 0 0 0 S 0.0 0.0 0:00.02 writeback 17 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kintegrityd 18 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset19 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset20 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset # 然后就使用awk命令定義一個(gè)數(shù)組 數(shù)組的名字就使用最后一個(gè)字段 數(shù)組的值就使用第六列 RES的值 文件內(nèi)容有點(diǎn)問題 所以顯示有點(diǎn)問題 [root@VM-8-7-centos shell_05]# tail -n +8 temp.txt | awk '{array[$13]=$6}END{for (i in array) print i,array[i]}'scsi_eh_0 0 kpsmoused 0 md 0 kintegrityd 0 systemd 43612 kauditd 0 kmpath_rdacd 0 migration/0 0 scsi_tmf_0 0 iscsi_eh 0 crypto 0 writeback 0 kthrotld 084188 khungtaskd 0 watchdog/0 0 rcu_sched 0 ksmd 0 edac-poller 0 kblockd 0 bioset 0 lru-add-drain 0 kaluad 0 kswapd0 0 watchdogd 0 netns 0 kthreadd 0 ata_sff 0 rcu_bh 0 deferwq 0 khugepaged 0 kdevtmpfs 0 kworker/0:0H 0 ipv6_addrconf 0 ksoftirqd/0 0# 將內(nèi)容進(jìn)行排序 sort -k排序命令 2表示按第二列排序 -n表示數(shù)字 -r表示降序 # 最后再顯示前面十行 [root@VM-8-7-centos shell_05]# tail -n +8 temp.txt | awk '{array[$13]=$6}END{for (i in array) print i,array[i]}' | sort -k 2 -n -r | head -1084188 systemd 43612 writeback 0 watchdogd 0 watchdog/0 0 scsi_tmf_0 0 scsi_eh_0 0 rcu_sched 0 rcu_bh 0 netns 0

    文件內(nèi)容的一些列字段有問題,但方法是這樣的:

  • 首先使用ps或top命令將內(nèi)容保存在一個(gè)臨時(shí)文件中
  • 使用tail -n +數(shù)字 從第一行開始顯示文件中的內(nèi)容
  • 然后在使用awk命令使用一個(gè)數(shù)組來存放每個(gè)進(jìn)行使用的內(nèi)容數(shù)
  • 然后使用sort 命令進(jìn)行排序
  • 最后使用head命令打印前10行數(shù)據(jù)。
  • 有個(gè)問題:現(xiàn)在 top命令并沒有將所有的進(jìn)程都打印出來 需要加一個(gè) -b 命令選項(xiàng)

    [root@VM-8-7-centos shell_05]# top -b -n 1 > temp.txt # 這里最后一個(gè)列 將$13改為了 $NF [root@VM-8-7-centos shell_05]# tail -n +8 temp.txt | awk '{array[$NF]=$6}END{for (i in array) print i,array[i]}' | sort -k 2 -n -r | head -10 beam.smp 84188 systemd-journal 59880 dockerd 55516 rsyslogd 40840 firewalld 29924 containerd 29440 tuned 18540 barad_agent 14076 iscsid 10124 polkitd 9500

    具體腳本如下:

    #!/usr/bin/bash # Author: hushang # Created Time: 2021-09-09 21:32 # Script Description: 統(tǒng)計(jì)使用內(nèi)容最大的前十個(gè)進(jìn)程memory(){# 首先創(chuàng)建一個(gè)臨時(shí)文件,然后將top命令輸出的內(nèi)容保存至臨時(shí)文件中memory_temp_file=`mktemp memory_use.XXXX`top -b -n 1 > $memory_temp_file# 統(tǒng)計(jì)內(nèi)存使用情況tail -n +8 $memory_temp_file | awk '{array[$NF]=$6}END{for (i in array) print array[i],i}' | sort -k 1 -n -r | head -10# 刪除臨時(shí)文件rm -f $memory_temp_file }memory# 結(jié)果如下 [root@VM-8-7-centos shell_05]# bash memory_use2.sh 84188 beam.smp 61240 systemd-journal 55516 dockerd 41532 rsyslogd 29924 firewalld 29440 containerd 18540 tuned 14076 barad_agent 10124 iscsid 9500 polkitd# 如果的統(tǒng)計(jì)cpu的話 改變一個(gè)字段即可 將awk命令中的$6 變?yōu)?$9 即可

    總結(jié)

    以上是生活随笔為你收集整理的shell脚本:介绍、语法、运算、流程控制、对文件/输出流处理、案例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。