sed和awk的用例及pam安全措施-第十五周

總結sed和awk的詳細用法;

sed用法

sed(Stream EDitor)是一款流編輯器,用來對文本進行過濾與替換操作。其原理是:通過文件或管道讀取文件內容,但是sed默認并不直接修改源文件,而是一次僅讀取文件的一行至模式空間(pattern space)根據sed指令進行編輯并輸出結果后清除模式空間,即所有的操作都是在模式空間中進行的。

sed和awk的用例及pam安全措施-第十五周

語法格式

sed [option]… ‘script’ inputfile…

OPTIONS選項

-n,–quite,–silent:靜默輸出,即不輸出模式中的內容至輸出

-e script:使用多個腳本指令執行編輯

-f /PATH/TO/SCRIPT_FILE:從指定的文件中讀取編輯腳本

-r:支持在腳本中使用正則表達式

-i,–in-place:直接在文件原處執行編輯,即修改源文件

SCRIPT,地址定界+編輯指令

地址定界

(1) 不給地址:對全文進行處理;

(2) 單地址

#:指定的行

$:文件的最后一行

/PATTERN/:被模式匹配到的每一行

(3) 地址范圍

m,n:指定m行到n行

#,+n:指定#行到#+n行

/pat1/,/pat2/:匹配到的pat1到pat2之間的行

#,/pat/:第#行到匹配到pat

(4) 步進:~

1~2:所有奇數行,從一開始,步進2

2~2:所有偶數行,從二開始,步進2

注意:如果//中正則表達式為空,則匹配最近一次正則表達式的匹配地址!

編輯命令

d:刪除

p:顯示模式空間的內容

a \text:在行后面追加內容,支持使用\n(換行符)實現多行追加

i \text:在行前面插入內容,支持使用\n(換行符)實現多行追加

c \text:替換行為單行或多行文本,支持使用\n(換行符)

w /PATH/TO/SOMEFILE:保存模式空間匹配到的行至指定文件中

r /PATH/FROM/SOMEFILE:讀取指定文件的文本流至模式空間中匹配到的行的行后

=:為模式空間中的行打印行號

!:取反條件

s/pattern/replacement/flags:替換,支持使用其他分隔符,如:s@@@, s###

替換標記(flags):
    #:替換行內匹配到的第#次的內容
    g:行內全局替換
    p:顯示替換成功的行
    w /PATH/TO/SOMEFILE:將替換后的結果保存至指定文件
replacement:
    &:用pattern匹配到的內容進行替換
    \n:在pattern中使用\(\)指定時,匹配第n個子串

【難點】高級編輯命令:

h:把模式空間中的內容覆蓋至保持空間中;
        H:把模式空間中的內容追加至保持空間中;
        g:把保持空間中的內容覆蓋至模式空間中;
        G:把保持空間中的內容追加至模式空間中;
        x:把模式空間中的內容與保持空間中的內容互換;
        n:顯示并清空模式空間,然后讀取匹配到的行的下一行覆蓋至模式空間;
        N:追加讀取匹配到的行的下一行至模式空間中;
        d:刪除模式空間中的行;
        D:刪除多行模式空間中的所有行;

        示例:
            sed  -n  'n;p'  FILE:顯示偶數行;
            sed  '1!G;h;$!d'  FILE:逆序顯示文件的內容;
            sed  ’$!d'  FILE:取出最后一行;
            sed  '$!N;$!D' FILE:取出文件后兩行;
            sed '/^$/d;G' FILE:刪除原有的所有空白行,而后為所有的非空白行后添加一個空白行;
            sed  'n;d'  FILE:顯示奇數行;
            sed 'G' FILE:在原有的每行后方添加一個空白行;

awk用法

其用法博大精深,且聽我細細道來

首先,grep,sed,awk三者區別,回顧一下:

grep, egrep, fgrep

文本過濾工具,只讀不寫,加上各種正則及關鍵字,那叫一個爽快。

sed

行編輯器,有模式空間及保持空間,實現文本行的編輯及輸出。

awk

報告生成器,格式化文本輸出;功能及其強大,不光可用正則,還可以使用條件判斷語句,函數、數組,不愧為上古神器。

有一點很重要,也很激勵人心,就是“結合awk與其他工具諸如grep和sed,將會使shell編程更加容易,也更有逼格?!?

awk命令的使用格式:

awk [options] ‘program’ file1,file2,…

awk [options] ‘PATTERN { action }’ file1,file2,…

program與PATTERN { action }的關系

很多同學在剛開始學習awk的時候,這里常常犯迷糊,me too!所以我覺得這個關系先理清楚,對awk往后的學習是有幫助的。

program包括PATTERN和ACTION,PATTERN和ACTION最少得有一個,語句之間用分號分隔

【理解關鍵點】模式( pattern ) 用于匹配輸入中的每行文本。對于匹配上的每行文本,awk 都執行對應的 動作( action )。模式和動作之間使用花括號隔開。awk 順序掃描每一行文本,并使用 記錄分隔符(一般是換行符)將讀到的每一行作為 記錄,使用 域分隔符( 一般是空格符或制表符 ) 將一行文本分割為多個 域, 每個域分別可以使用 $1, $2, … $n 表示。$1 表示第一個域,$2 表示第二個域,$n 表示第 n 個域。 $0 表示整個記錄。模式或動作都可以不指定,缺省模式的情況下,將匹配所有行。缺省動作的情況下,將執行動作 {print},即打印整個記錄。

先來說說ACTION

其中最常用的ACTION參數之一就是print和printf了,前者實現打印輸出,后者實現格式化輸出

print

語法:

print item1, item2, …

要點

(1) 逗號分隔符;

(2) 輸出的各item可以字符串,也可以是數值;當前記錄的字段、變量或awk的表達式;

(3) 如省略item,相當于print $0,打印整行字符

printf命令,這個就很有內涵了

要點:

(1) FORMAT必須給出;

(2) 不會自動換行,需要顯式給出換行控制符,\n

(3) FORMAT中需要分別為后面的每個item指定一個格式化符號;

語法:

printf 格式符/修飾符, item1, item2, …

格式符:
        %c: 顯示字符的ASCII碼;
        %d, %i: 顯示十進制整數;
        %e, %E: 科學計數法數值顯示;
        %f:顯示為浮點數;
        %g, %G:以科學計數法或浮點形式顯示數值;
        %s:顯示字符串;
        %u:無符號整數;
        %%: 顯示%自身;

修飾符:
        #[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度;
        %3.1f
        -: 左對齊
        +:顯示數值的符號

記住哦,格式符和修飾符可以靈活組合使用

ACTION還支持以下干貨,

(1) Expressions表達式

(2) Control statements:if, while等;

(3) Compound statements:組合語句;

(4) input statements

(5) output statements(print printf)

我們來看看控制語句:

(1)if(condition) {statments} :單分支if語句

(2)if(condition) {statments} else {statements} :雙分支if語句

(3)while(conditon) {statments}

(4)do {statements} while(condition) :循環體

(5)for(expr1;expr2;expr3) {statements}

(6)break

(7)continue

(8)delete array[index]

(9)delete array

(10)exit

支持這么多,已經看傻,下面一個個來看看:

if-else

語法:if(condition) statement [else statement]

    ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd

    ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd

    ~]# awk '{if(NF>5) print $0}' /etc/fstab

    ~]# df -h | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}'

    使用場景:對awk取得的整行或某個字段做條件判斷;

while循環

語法:while(condition) statement
    條件“真”,進入循環;條件“假”,退出循環;

    ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg

    ~]# awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) {print $i,length($i)}; i++}}' /etc/grub2.cfg

    使用場景:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用;

do-while循環

語法:do statement while(condition)
意義:至少執行一次循環體

for循環

語法:for(expr1;expr2;expr3) statement

    for(variable assignment;condition;iteration process) {for-body}

    ~]# awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

    特殊用法:
        能夠遍歷數組中的元素;
        語法:for(var in array) {for-body}

switch語句

語法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; ...; default: statement}

next

提前結束對本行的處理而直接進入下一行;

~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

數組array

關聯數組:array[index-expression]

    index-expression:
        (1) 可使用任意字符串;字符串要使用雙引號;
        (2) 如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”;

        若要判斷數組中是否存在某元素,要使用"index in array"格式進行;
            weekdays[mon]="Monday"

        若要遍歷數組中的每個元素,要使用for循環;
            for(var in array) {for-body}

函數

內置函數
    數值處理:
        rand():返回0和1之間一個隨機數;

    字符串處理:
        length([s]):返回指定字符串的長度;
        sub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其第一次出現替換為s所表示的內容;
        gsub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其所有出現均替換為s所表示的內容;
        split(s,a[,r]):以r為分隔符切割字符s,并將切割后的結果保存至a所表示的數組中;

好,上邊ACTION啰嗦完了,哈哈哈哈哈,下面就要高潮咧O(∩_∩)O哈哈~

PATTERN

PATTERN有什么,有很多,超乎你的想象,它支持

(1) empty:空模式,匹配每一行;

        (2) /regular expression/:僅處理能夠被此處的模式匹配到的行;

        (3) relational expression: 關系表達式;【結果有“真”有“假”;結果為“真”才會被處理】;

            【真:結果為非0值,非空字符串】這個跟bash的命令返回值不一樣;

        (4) line ranges:行范圍,
            startline,endline:/pat1/,/pat2/

            例子:[root@CentOS7 ~]# awk -F: '/^h/,/^u/{print $1}' /etc/passwd

            注意: 不支持直接給出數字的格式

            可以使用如下方式:
            ~]# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd

        (5) BEGIN/END模式
            BEGIN{}: 僅在開始處理文件中的文本之前執行一次;
            END{}:僅在文本處理完成之后執行一次    ;

選項[options]

-F:指明輸入時用到的字段分隔符;

-v var=value: 自定義變量;

awk的options主要用來定義各種變量和使用各種內建變量。

內建變量

FS:input field seperator,默認為空白字符;
            OFS:output field seperator,默認為空白字符;
            RS:input record seperator,輸入時的換行符;
            ORS:output record seperator,輸出時的換行符;

            NF:number of field,字段數量
                {print NF}, {print $NF} 它們之間是有區別的,NF是有多少個字段數量,而$NF表示最后一個字段的內容
            NR:number of record, 行數;
            FNR:各文件分別計數;行數;

            $0:代表一行,讀一行進行切片

            FILENAME:當前文件名;

            ARGC:命令行參數的個數;
            ARGV:數組,保存的是命令行所給定的各參數;

            PS:在awk中要做變量替換,是不能用引號引起來的

自定義變量

(1) -v var=value  #變量名區分字符大小寫哦;

            (2) 在program中直接定義

好了,awk就介紹到這里,下面來寫例子

例子1:顯示/etc/passwd的賬戶

#cat /etc/passwd |awk  -F ':'  '{print $1}'  
root
daemon
bin
sys

上邊這種是awk+action的示例,每行都會執行action{print $1}。

-F指定域分隔符為’:’。

例子2:搜索/etc/passwd有root關鍵字的所有行

#awk -F: '/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

上邊這種是pattern的使用示例,匹配了pattern(這里是root)的行才會執行action(沒有指定action,默認輸出每行的內容)。

搜索支持正則,例如找root開頭的: awk -F: ‘/^root/’ /etc/passwd

例子3:搜索/etc/passwd有root關鍵字的所有行,并顯示對應的shell

# awk -F: '/root/{print $7}' /etc/passwd             
/bin/bash

上邊這里指定了匹配了pattern(這里是root)的行才會執行action{print $7}

例子4:刪除/boot/grub/grub.conf文件中所有行的行首的空白字符

sed ‘s/^[[:space:]]+//’ /boot/grub/grub.conf

這里的sed使用了查找替換,思路就是先查找文件中所有行的行首的空白字符,用正則的行首錨定空字符,之后查找替換為空,即刪除。

例子5:刪除/etc/fstab文件中所有以#開頭,后跟至少一個空白字符的行的行首的#和空白字符

sed ‘s/^#[[:space:]]*//’ /etc/fstab

同樣是查找替換的套路,參照例子4

例子6:把/etc/fstab文件的奇數行另存為/tmp/fstab.3

sed ‘1~2!d’ /etc/fstab > /tmp/fstab.3

sed ‘1~2w /tmp/fstab.3’ /etc/fstab

這里用到了sed地址定界中的步進+編輯命令,兩種不同的編輯命令實現,真是飛刀又見飛刀,套路又見套路,套路就是熟悉其語法,命令,靈活組合使用。

例子7:echo一個文件路徑給sed命令,取出其基名;進一步地,取出其路徑名

路徑名

echo “/tmp/test/fstab” | sed ‘s#[^/]+\?$##’

上邊sed的#為分隔符,[^/]指匹配指定范圍外的任意單個字符,

+:匹配其前面的字符1次或多次:即其前面的字符要出現至少1次;

\?:匹配其前面的字符0次或1次;即其前面的字符是可有可無的;

$:行尾錨定;用于模式的最右側

基名

echo “/tmp/test/fstab” | sed ‘s#(\/.*\/)##’

上邊的sed分隔符為#,用到了sed的查找替換、正則表達式及其分組,形式為\(正則表達式\)

正則為\/.*\/,其中\為轉移符,正則抽取出來就是/.*/  意思就是匹配到/開頭的以/結尾期間的任意單個字符任意次。

各位應該明白了吧。

例子8:統計指定文件中所有行中每個單詞出現的次數

awk ‘{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}’ /etc/fstab

[root@CentOS7 ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
swap 2
fstab(5), 1
filesystems, 1
on 1
/etc/fstab 1
/boot 1
more 1
mount(8) 1
pages 1
'/dev/disk' 1
/dev/mapper/cl_centos7-swap 1
blkid(8) 1
See 1
/dev/mapper/cl_centos7-root 1
for 1
and/or 1
anaconda 1
/ 1
findfs(8), 1
under 1
17:33:09 1
Created 1
UUID=fe2021fb-ac21-474d-8256-f72b87fc915a 1
0 6
info 1
Accessible 1
22 1
# 7
defaults 3
xfs 2
man 1
are 1
reference, 1
Mar 1
by 2
maintained 1
2017 1
Wed 1
[root@CentOS7 ~]#

7、統計當前系統上所有tcp連接的各種狀態的個數;

netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key,”t”,state[key]}’

例子

root@xxx:~# netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'
FIN_WAIT2 t 71
CLOSE_WAIT t 1
TIME_WAIT t 2049
ESTABLISHED t 1392
LAST_ACK t 3
FIN_WAIT1 t 4

8、統計指定的web訪問日志中各ip的資源訪問次數:

awk ‘{ip[$1]++}END{for(i in ip) print i,ip[i]}’ /opt/nginx/logs/access.log

9、寫一個腳本:定義一個數組,數組元素為/var/log目錄下所有以.log結尾的文件的名字;顯示每個文件的行數;

[root@CentOS7 ~]#  cat week15_title9.sh 
#!/bin/bash

files=/var/log/*.log

for i in $files
do
    wc -l $i
done

輸出如下:

[root@CentOS7 ~]# ./week15_title9.sh 
248 /var/log/boot.log
9 /var/log/openlmi-install.log
177 /var/log/vmware-install.log
326 /var/log/vmware-vmsvc.log
85 /var/log/vmware-vmusr.log
10 /var/log/wpa_supplicant.log
436 /var/log/Xorg.0.log
320 /var/log/Xorg.9.log
328 /var/log/yum.log
[root@CentOS7 ~]#

10、寫一個腳本,能從所有同學中隨機挑選一個同學回答問題;進一步地:可接受一個參數,做為要挑選的同學的個數;

[root@CentOS7 ~]# cat week15_title10.sh
#!/bin/bash

if [ $1 ];then  #判斷有無腳本參數傳入,如有則執行,沒有就執行else的語句
    for((i=1;i<=$1;i++));do
        a=$[$RANDOM%11] #定義一個0~10的隨機數
        echo $a
    done
else
    a=$[$RANDOM%11]
    echo $a
fi

11、授權centos用戶可以運行fdisk命令完成磁盤管理,以及使用mkfs或mke2fs實現文件系統管理;

visudo
centos  ALL=(root)      NOPASSWD:/sbin/fdisk,/sbin/mke2fs,/sbin/mkfs

12、授權gentoo用戶可以運行邏輯卷管理的相關命令;

visudo
gentoo  ALL=(root)      lvm

13、基于pam_time.so模塊,限制用戶通過sshd服務遠程登錄只能在工作時間進行;

vim /etc/ssh/sshd_config 
UsePAM yes  #開啟Pam模塊認證


/lib64/security/pam_time.so #確保pam_time.so存在 

vim /etc/pam.d/sshd
增加  account    required     pam_time.so

vim /etc/security/time.conf
添加 *;*;*;MoTuWeThFr0900-1800

14、基于pam_listfile.so模塊,定義僅某些用戶,或某些組內的用戶可登錄系統;

[root@localhost ~]# vim /etc/sshd_userlist
root
centos
gentoo

chmod 600 /etc/sshd_userlist
chown root /etc/sshd_userlist
vim /etc/pam.d/sshd 
#auth       required     pam_listfile.so item=user sense=allow file=/etc/sshd_userlist onerr=succeed

原創文章,作者:N24_Jerry,如若轉載,請注明出處:http://www.www58058.com/77539

(0)
N24_JerryN24_Jerry
上一篇 2017-06-05 08:57
下一篇 2017-06-05 19:36

相關推薦

  • 計算機相關簡介和linux相關簡介

    一、計算機相關簡介與linux的一些概念 計算機系統 由硬件(Hardware)系統和軟件(Software)系統兩大部分構成: 硬件系統 :CPU(控制器、運算器),內存儲器(RAM、ROM),外存儲器(硬盤等),輸入設備(鍵盤、鼠標等),輸出設備(顯示器等),其他設備相關設備。  軟件系統 :系統軟件(操作系統,數…

    Linux干貨 2017-02-18
  • httpd功能配置之訪問控制

       httpd服務可以實現對資源訪問控制,可以根據IP地址和用戶兩種方式進行控制。    一、用戶認證控制      1、在站點根目錄下創建一個目錄及一個頁面文件      2、修改/var/httpd/conf/httpd.conf文件   &n…

    Linux干貨 2016-03-11
  • Linux系統程序包管理工具-RPM

    一、rpm是什么 RPM 是RPM Package Manager(RPM軟件包管理器)的縮寫,這一文件格式名稱雖然打上了RedHat的標志,但是其原始設計理念是開放式的。RPM包管理器(RPM)是一個強大的命令行驅動的包管理系統能夠安裝、卸載、驗證、查詢和更新計算機軟件包。每個軟件包包括存檔的文件連同包和它的版本信息,描述等。還有一個庫API,允…

    Linux干貨 2015-11-19
  • keepalived的初級使用

        1、雙主模型的ipvs高可用   一、雙主模型的ipvs高可用     1)網絡結構圖       2)、ipvs的類型是dr模型,調度算法是rr       RS1和RS2都是centos6.8 對RS1和RS2的配置:…

    Linux干貨 2017-05-15
  • 設計模式(八)裝飾器模式Decorator(結構型)

    1. 概述        若你從事過面向對象開發,實現給一個類或對象增加行為,使用繼承機制,這是所有面向對象語言的一個基本特性。如果已經存在的一個類缺少某些方法,或者須要給方法添加更多的功能(魅力),你也許會僅僅繼承這個類來產生一個新類—這建立在額外的代碼上。       通過繼…

    Linux干貨 2015-07-03
  • awk,systemctl,破解7root口令

    awk -F 指明輸入時用到的字段分隔符 默認空格為分隔符 -v 自定義變量 基本格式:awk [options] 'program' file $1,$2..$n稱為域標識,$0為所有域。 文件的每一行稱為記錄 awk '{print}' /etc/passwd 默認 print $0 顯示全段   awk…

    Linux干貨 2016-10-05
欧美性久久久久