linux —— shell 編程(文本處理)

導讀

本文爲博文 linux —— shell 編程(總體框架與基礎筆記)的第4小點的拓展。(本文全部語句的測試均在 Ubuntu 16.04 LTS 上進行)html


目錄
  1. 基本文本處理
  2. 流編輯器sed
  3. awk模式掃描與處理語言
一、基本文本處理

sort :用於排序,經常使用參數 -t 指定一行的分隔符 -k 指定具體排序的規則 -d 按字典序排列  -f 忽略大小寫linux

    -u (unique)丟棄相同指定字段的記錄正則表達式

unique:報告或刪除文件中重複的行。 -c 在輸出行前加上出現的次數    -d  (duplicated)顯示重複的行  shell

                  -u 僅顯示不重複的行 編程

wc:  統計文本行數,字數和字符數。    -c 字符數    -w  單詞數    -l  行數數組

pr:將文本轉換成適合打印的格式。   -c 顯示的列數(截斷超出的部分)bash

fmt: 優化文本的格式。  -w 設置一行顯示的最大行寬   -s  只對過長的行進行換行,不要自動回填。框架

fold:限制文本寬度(強行截斷並換行)。 -w 指定寬度  -s 只在空格處換行。編輯器

cut :截取行的字段。   -delimiter  設置字段分割符 -f List 設置截取的域  ide

           List能夠是M,M-,M-N -M;能夠用逗號指定多個

join:鏈接兩個文件的數據字段。  join file1 file2  -1 M  -2 N    M、N指定匹配的字段

tr: 文本替換。 tr set set :將str1上字符替換成str2上對於位置的字符; (能夠是 tr 'a-z' 'A-Z')

        tr {-d|-s} set :-d 刪除set上的每個字符 ;-s 除去連續出現的set中的字符,至只剩下單個

        tr -c (complement 互補)使用set1的外的其餘字符 [例子:tr -cs '[:lower:][:upper:]' '[\n*]' 單詞表]

二、流編輯器sed

0)sed 的做用和工做方式

sed 是一個非交互式的的行編輯器,工做時,從指定的輸入讀入一行數據存入被稱爲模式空間(Pattern Space) 的臨時緩衝區,而後按照指定的sed編輯命令處理緩衝區裏面的內容,將結果輸出到標準輸出後從模式空間中刪除,而後繼續讀取下一行繼續工做。

1) 地址範圍

sed -e '1,5d'  test.txt
sed -e '/^#/d' test.txt

規則表達式中使用的表達式字符:

字符 描述
^ 與行首匹配

$

與行尾匹配

.

與任意一個字符匹配
* 與以前一個字符的零個或多個出現匹配
[] 與[]之間的全部字符匹配

 2) 參數

-e     將腳本添加到命令執行,如上面的 '/^#/d'

-n    禁止模式空間的自動打印

替換文本:   sed -e "s/benson/BENSON/g"  將benson 替換成大寫

      sed -e "1,10s/benson/BENSON/g" 將1-10行的benson變成大寫

          s/// 的 「/」能夠被替換:好比 sed -e "s:/usr/local:/usr:g" 

多條命令一塊兒執行:  sed -n -e "=;p"   打印行號;打印行 (等價與 sed -e "=" -e "p" )

多條命令於同一地址範圍:sed -n -e '1,5{s/benson/BENSON/g;s/laur/LAUR/g}'

把命令放在文件fsed裏:sed -n -f fsed 

三、awk模式掃描與處理語言

awk 具備成爲一門語言應有的要素:變量,函數等,是強大的處理工具。

例子:

awk -F ":" '{print "USER:" $1  "\tSHELL: " $7 }'  /etc/passwd
結果:
USER:root    SHELL: /bin/bash
USER:daemon    SHELL: /usr/sbin/nologin
USER:sync    SHELL: /bin/sync

上面的命令也能夠寫入文件file.awk中:

awk -f file.awk /etc/passwd
BEGIN{ FS=":" }
{
    print "USER:" $1  "\tSHELL: " $7 
}
file.awk
3.1 awk的變量和數組

1)用戶自定義變量

命名規則:[A-Za-z_][A-Za-z0-9_]*

2) 經常使用的內建變量

變量 說明
FILENAME 當前輸入的文件名稱
FNR 當前輸入的文件的記錄數
FS 字段分隔符(支持正則表達式),默認空格
NF 當前記錄的字段數
NR 在工做(job)中的記錄數
OFS 輸出字段分隔字符
ORS 輸出記錄分隔字符(默認爲「\n」)
RS 輸入記錄分隔字符

3) awk數組  的字符索引支持數字、字符串

sit[google]="https://google.com"
sit[baidu]="http;//baidu.com"

數組存儲是稀疏的,可直接定義以下兩項:
x[1]=1234
x[1000]=234234

delete x  將刪除數組裏全部的元素

刪除後,能夠繼續定義以下:
x=567

訪問環境變量:ENVIRON["PATH"]

3.2 算數運算
awk的運算符 
運算符 描述 例子
=  +=  *=   /=  ^=  **= 賦值  
?= C條件表達式  
||   && 邏輯與或  
++-- 自增自減  
~   ~! 匹配正則表達式和不匹配正則表達式  
<   <=  >  >=  !=  == 關係運算符  
空格 鏈接  
+ - 加、減  
* /  % 乘除 求餘  
+  -  ! 一元加減,邏輯非  
^  *** 求冪  
$ 字段引用  
in 數組成員  

awk支持的算數函數:  

    sin(x) cos(x) atan2(x,2) :x,y 範圍內的餘切 int(x):沒有舍入地取整 exp(x)求冪 log(x):天然對數 sqrt(x) 

    rand():產生>=0 <1的隨機數 srand(x):x是rand()的種子

3.3 條件和循環語句

條件語句和循環語句與C相似,支持break,continue(能夠不使用;結尾)

例子:將下面記錄每組一行輸出

abc,123
tttt  dddd

ddd,324
ssss  ssdd
sdfsd sdf 

dddd
sfdfsdf
待處理數據
BEGIN{
        FS="\n"
        RS=""    # RS設置爲""將能夠解析多行記錄(以空行分隔)
        ORS=""      #輸出記錄分隔符不要換行
}
{
        x=1
        while(x<NF)
        {
                print $x "\t"
                x++
        }
        print $NF "\n"
}
使用while循環

結果:

abc,123    tttt  dddd
ddd,324    ssss  ssdd    sdfsd sdf
dddd    sfdfsdf
處理結果
3.4 自定義函數

在函數中,指定的參數將被當作局部變量,而全部函數體內未出如今參數列表中的變量會被視爲全局性。爲此,awk容許聲明過多的參數用於局部使用如:

function add(x,y,      sum)
{
sum = x+y
return sum
}

若是須要使用函數進行引用傳遞,只能經過傳入數組來實現:

引用傳遞
3.5 字符串處理

格式化輸出:

printf("%s have %d jobs","somebody",3)
strout = sprintf("%s have %d jobs","somebody",3)

格式化輸出的轉義字符:c s d ld (十進制長整數) u lu x lx o lo e(科學計數法表示的浮點數) f g(e或f中比較短的一種)

printf 修飾符:  - 左對齊     #顯示八進制時在前面加個0;顯示十六進制時在前面加0x  

         +顯示defg 轉換的整數時,加上正負號    0  填充空白爲0

        具體的格式爲:%-width.precision fotmat-specifier

awk內置字符串函數:

awk函數 描述
sub(/reg/,newsubstr,str) 替換第一個匹配的字符串
gsub(/reg/,newsubstr,str) 替換全部匹配
index(str,substr) 返回substr在str中的索引
length(str) 長度
match(str,/reg/) 若是在str中找到正則表達式/reg/匹配的串,則返回出現的位置,未找到則返回0
split(str,array,sep) 使用sep分隔到array
substr(str,position[,length]) 返回str從position開始的length個字符
tolower(str) 變小寫
toupper(str) 變大寫
sprintf("fmt",expr) 格式化返回字符串

 

3.6 多文件處理
10001 南京 佛擋殺佛 sdfsdf
10002 天津 發生地方  雙方的發生
10003 石家莊 發生地方 發生地方
a.txt
11000,南京
11003,天津
12000,河北省
13000,品上線
12344,石家莊
b.txt
BEGIN{
        FS="[ ,]"
        OFS=","
}

NR <= FNR{
        array[$2]=$1
}
NR > FNR{
        print $1,$2,array[$2]
}
join.awk
awk  -f join.awk a.txt b.txt
11000,南京,10001
11003,天津,10002
12000,河北省,
13000,品上線,
12344,石家莊,10003
執行結果
相關文章
相關標籤/搜索