1. 程式人生 > >[Shell]字元擷取命令:cut, printf, awk, sed

[Shell]字元擷取命令:cut, printf, awk, sed

【cut命令】

  cut [選項] 檔案

    -f 列號        ( --field 提取第幾列 )

    -d 分隔符    ( --delimiter 按照指定分隔符分割列 )

  vi user.txt

  ( 行間分隔符為製表符Tab,cut的預設分割符是製表符 )

  提取系統的使用者名稱和uid:

  cut -d ":" -f 1,3 /etc/passwd

  與grep組合使用:( 假設批量新增100個普通使用者,或需要批量刪除,那麼需要提取普通使用者的名字 )

    useradd user1

    useradd user2

    useradd user3

   ( 所有系統使用者登入目錄都是/sbin/nologin , 通過匹配/bin/bash 提取所有能登入的使用者 , -v 取反選擇不匹配root的行,再用cut匹配列提取使用者名稱;把結果賦給變數,通過迴圈刪除 )

    cat /etc/passwd | grep "/bin/bash" | grep -v "root" | cut -d ":" -f 1

  cut命令的侷限:   

   ( 提取系統盤使用率 )

  df -h

    df -h | grep "sda3" | cut -f 5      # 只能匹配出行所有內容,因為分隔符是空格,不是Tab

    ​df -h | grep "sda3"
| cut -d " " -f 5   # 無法匹配出想要的結果,因為分割符是嚴格匹配,如果實際內容分割符有兩個空格,無法得出正確結果

【printf】

  printf ‘輸出型別輸出格式’ 內容

  輸出型別:

  %ns:    輸出字串。n是數字,指輸出幾個字元

  %ni:    輸出整數。n是數字,指輸出幾個數字

  %m.nf:輸出浮點數。m和n是數字,分別指輸出的整數位數和小數位數。如%8.2f代表共輸出8位數,其中2是小數,6是整數。

  輸出格式:

  \a   :    輸出警告聲音

  \b    :    輸出退格鍵,也就是Backspace鍵

  \f    :    清除螢幕

  \n    :    換行

  \r    :    回車,也就是Enter鍵

  \t    :    水平輸出退格鍵,也就是Tab鍵

  \v    :    垂直輸出退格鍵,也就是Tab鍵
 printf %s 1 2 3 4 5 6    # 把123456當成一個字串輸出,沒有格式



  printf %s %s %s 1 2 3 4 5 6    # 把%s%s123456當做字串輸出,沒有格式



  printf '%s ' 1 2 3 4 5 6    # 把1 2 3 4 5 6當做字串輸出,輸出格式為空格



  printf '%s\n' 1 2 3 4 5 6    # 輸出格式為1個一行



  printf '%s %s %s' 1 2 3 4 5 6    # 把內容當做字串三個為一組輸出,1 2 34 5 6



  printf '%s %s %s\n' 1 2 3 4 5 6    # 輸出格式為3個一行



  printf '%s' $(cat user.txt)    # 輸出文字內容為字串



  printf '%s\t %s\t %s\t %s\n' $(cat user.txt)  # 把文字內容格式化輸出

【awk】

  awk的標準輸出命令是printf,預設分割符是空格或製表符。cut命令不能在風格符是空格的字串中擷取列,只能是製表符或具體的分割符。

  1. awk ‘條件1{動作1} 條件2{動作2}…’ 檔名

  ( 如果條件1,執行動作1;如果條件2,執行動作2 )

    條件(pattern):

    一般使用關係表示式作為條件

    x > 10    判斷變數x是否大於10

    x>=10    大於等於

    x<=10    小於等於

    動作(Action)

      格式化輸出

    流程控制語句
   awk '{printf $2 "\t" $3"\n"}' user.txt

   ( 大括號前面沒有條件,直接執行命令,這裡的printf 是awk的命令,23 提取檔案第三列,$0 提取所有列 )

   df -h | awk '{print $1 "\t" $5 "\t" $6 "\t"}'

   ( 列印三列,這裡的print是awk的命令,系統並沒有print命令,所以只能在awk裡使用;與printf的區別是:print會自動在行尾加換行符,而printf不會 )

df -h | grep sda3 | awk '{print $5}' | cut -d '%' -f 1

( 提取系統已使用硬碟空間,可以把結果賦給一個變數,判斷是否大於某個值,進行報警 )

  2. BEGIN:先執行一條多餘的動作

awk 'BEGIN{print "this is a text"} {print $2 "\t" $3}' user.txt

  3. END:用於在所有命令處理完之後執行

  4. FS內建變數:用於定義分割符,如果需要手工定義分割符,一定要在分割符前面加BEGIN;

   awk 'BEGIN{FS=":"} END{print "this is end text"} {print $1 "\t" $3}' /etc/passwd

  5. 關係運算符:
  

  cat user.txt | grep -v ID | awk '$4 > 18 {printf $2 "\n"}'

   ( user.txt中不包含ID這行,提取滿足條件為第四列值大於18的第二列 )

【sed】

  sed是一種幾乎包括在所有Unix平臺的輕量級流編輯器。sed主要是用來將資料進行選取、替換、刪除、新增的命令。(可以放在管道符之後處理)

  sed [選項] ‘[動作]’ 檔名

    sed命令有兩種形式:sed [options] ‘command’ file(s);sed [options] -f scriptfile file(s)

  選項:

  -n    :    一般sed命令會把所有資料都輸出到螢幕;如果加入此選項,則只會把經過sed命令處理的行輸出到螢幕。

  sed -n '2p' user.txt    # 輸出第二行



  -e    :    允許對輸入資料應用多條sed命令編輯

    -f :  新增指令碼檔案的內容到執行的動作

  -i    :    用sed的修改結果直接修改讀取資料的檔案,而不是由螢幕輸出

  動作:(要加雙引號)

  a\    :    追加,在當前行後新增一行或多行。新增多行時,除最後一行外,每行末尾需要用"\"代表資料未完結。

  c\    :    行替換,用c後面的字串替換原資料行,替換多行時,除最後一行外,每行末尾需要用"\"代表資料未完結。

  i\    :    插入,在當前行前插入一行或多行。插入多行時,除最後一行外,每行末尾需要用"\"代表資料未完結。

  d    :    刪除,刪除指定的行。

  p    :    列印,輸出指定的行。

  s    :    字串替換,用一個字串替換另外一個字串。格式為“行範圍s/舊字串/新字串/g”(和vim中的替換格式類似)

  sed -n ‘2p’ user.txt     # 輸出第二行, p一般都要和-n使用,不加-n會顯示出所有的行

  df -h | sed -n ‘2p’      # 管道符結果作為操作內容

  sed ‘2,4d’ user.txt     # 刪除檔案的第2行到第4行,顯示剩下的行,沒有加 i 選項,不會更改檔案內容

  sed ‘2a hello’ user.txt   # 在第二行後追加hello,僅僅修改命令輸出

  sed ‘2i hello \

    world’ user.txt     # 在第二行前插入兩行資料,僅僅修改命令輸出

  sed ‘2c No person’ user.txt # 把第二行替換為No person

  sed ‘2s/M/F/g’ user.txt   # 把第二行的M替換為F後輸出

  sed -i ‘2s/M/F/g’ user.txt  # 把替換後的結果寫入檔案

  sed -e ‘s/zhang//g ; s/wang//g’ user.txt # -e允許多條命令順序執行,用分號隔開,s前面不加數字表示所有行