awk與sed區別


引用:linux工具快速教程:https://linuxtools-rst.readthedocs.io/zh_CN/latest/index.html#

1、sed 文本替換利器

首處替換
sed 's/text/replace_text/' file //替換每一行的第一處匹配的text

全局替換
sed 's/text/replace_text/g' file

默認替換后,輸出替換后的內容,如果需要直接替換原文件,使用-i::
sed -i 's/text/repalce_text/g' file

移除空白行
sed '/^$/d' file

變量轉換,已匹配的字符串通過標記&來引用.
echo this is en example | sed 's/\w\+/[&]/g'
結果:[this] [is] [en] [example]

子串匹配標記,第一個匹配的括號內容使用標記 \1 來引用
sed 's/hello\([0-9]\)/\1/'

雙引號求值
sed通常用單引號來引用;也可使用雙引號,使用雙引號后,雙引號會對表達式求值
sed 's/$var/HLLOE/'

當使用雙引號時,我們可以在sed樣式和替換字符串中指定變量;
eg:
p=patten
r=replaced
echo "line con a patten" | sed "s/$p/$r/g"
結果:line con a replaced

其它示例
字符串插入字符:將文本中每行內容(ABCDEF) 轉換為 (ABC/DEF)
sed 's/^.\{3\}/&\//g' file

2、awk 數據流處理工具

1) awk腳本結構

    awk ' BEGIN{ statements } statements2 END{ statements } '

工作方式
    1.執行begin中語句塊;
    2.從文件或stdin中讀入一行,然后執行statements2,重復這個過程,直到文件全部被讀取完畢;
    3.執行end語句塊;
2)print 打印當前行

使用不帶參數的print時,會打印當前行
    echo -e "line1\nline2" | awk 'BEGIN{print "start"} {print } END{ print "End" }'

print 以逗號分割時,參數以空格定界;
    echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
    print var1, var2 , var3; }'
    $>v1 V2 v3

使用-拼接符的方式(""作為拼接符);
    echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
    print var1"-"var2"-"var3; }'
    $>v1-V2-v3

3)特殊變量: NR NF $0 $1 $2

  NR:表示記錄數量,在執行過程中對應當前行號;

  NF:表示字段數量,在執行過程總對應當前行的字段數;

  $0:這個變量包含執行過程中當前行的文本內容;

  $1:第一個字段的文本內容;

  $2:第二個字段的文本內容;

echo -e "line1 f2 f3\n line2 \n line 3" | awk '{print NR":"$0"-"$1"-"$2}'

打印每一行的第二和第三個字段
    awk '{print $2, $3}' file

統計文件的行數
    awk ' END {print NR}' file

累加每一行的第一個字段
    echo -e "1\n 2\n 3\n 4\n" | awk 'BEGIN{num = 0 ; \
    print "begin";} {sum += $1;} END {print "=="; print sum }'
4)傳遞外部變量
    var=1000
    echo | awk '{print vara}' vara=$var #  輸入來自stdin
    awk '{print vara}' vara=$var file # 輸入來自文件

5)用樣式對awk處理的行進行過濾
    awk 'NR < 5' #行號小於5
    awk 'NR==1,NR==4 {print}' file #行號等於1和4的打印出來
    awk '/linux/' #包含linux文本的行(可以用正則表達式來指定,超級強大)
    awk '!/linux/' #不包含linux文本的行

6)設置定界符
使用-F來設置定界符(默認為空格
    awk -F: '{print $NF}' /etc/passwd

7)讀取命令輸出
使用getline,將外部shell命令的輸出讀入到變量cmdout中::

    echo | awk '{"grep root /etc/passwd" | getline cmdout; print cmdout }'
8)在awk中使用循環

    for(i=0;i<10;i++){print $i;}
    for(i in array){print array[i];}

eg:以下字符串,打印出其中的時間串::

    2015_04_02 20:20:08: mysqli connect failed, please check connect info
    $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F ":" '{ for(i=1;i<=;i++) printf("%s:",$i)}'
    >2015_04_02 20:20:08:  # 這種方式會將最后一個冒號打印出來
    $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F':' '{print $1 ":" $2 ":" $3; }'
    >2015_04_02 20:20:08   # 這種方式滿足需求

而如果需要將后面的部分也打印出來(時間部分和后文分開打印)::

    $echo '2015_04_02 20:20:08: mysqli connect failed, please check connect info'|awk -F':' '{print $1 ":" $2 ":" $3; print $4;}'
    >2015_04_02 20:20:08
    >mysqli connect failed, please check connect info

以逆序的形式打印行:(tac命令的實現)::

    seq 9| \
    awk '{lifo[NR] = $0; lno=NR} \
    END{ for(;lno>-1;lno--){print lifo[lno];}
    } '
9)awk結合grep找到指定的服務,然后將其kill掉
    ps -fe| grep msv8 | grep -v MFORWARD | awk '{print $2}' | xargs kill -9;

10)awk實現head、tail命令

head
    awk 'NR<=10{print}' filename

 tail
    awk '{buffer[NR%10] = $0;} END{for(i=0;i<11;i++){ \
    print buffer[i %10]} } ' filename

11)打印指定列
awk方式實現
    ls -lrt | awk '{print $6}'

cut方式實現
    ls -lrt | cut -f6

12)打印指定文本區域
確定行號
    seq 100| awk 'NR==4,NR==6{print}'

確定文本
打印處於start_pattern 和end_pattern之間的文本::
    awk '/start_pattern/, /end_pattern/' filename

示例::

    seq 100 | awk '/13/,/15/'
    cat /etc/passwd| awk '/mai.*mail/,/news.*news/'
13)awk常用內建函數

index(string,search_string):返回search_string在string中出現的位置
sub(regex,replacement_str,string):將正則匹配到的第一處內容替換為replacement_str;
match(regex,string):檢查正則表達式是否能夠匹配字符串;
length(string):返回字符串長度

    echo | awk '{"grep root /etc/passwd" | getline cmdout; print length(cmdout) }'

printf 類似c語言中的printf,對輸出進行格式化::

    seq 10 | awk '{printf "->%4s\n", $1}'

14)迭代文件中的行、單詞和字符

迭代文件中的每一行 while 循環法

    while read line;
    do
    echo $line;
    done < file.txt

    改成子shell:
    cat file.txt | (while read line;do echo $line;done)


awk法

    cat file.txt| awk '{print}'

迭代一行中的每一個單詞

    for word in $line;
    do
    echo $word;
    done


迭代每一個字符
${string:start_pos:num_of_chars}:從字符串中提取一個字符;(bash文本切片)

${#word}:返回變量word的長度

    for((i=0;i<${#word};i++))
    do
    echo ${word:i:1);
    done


以ASCII字符顯示文件

    $od -c filename

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM