主頁 > 後端開發 > Linux四劍客find+grep+sed+awk

Linux四劍客find+grep+sed+awk

2023-03-10 07:20:12 後端開發

find,grep,sed,awk

目錄
  • find,grep,sed,awk
    • 1.find【擅長在目錄下找檔案】
      • 1.1 常用查詢選項option
      • 1.2 根據時間戳進行搜索
      • 1.3 對查找到的檔案如何操作
      • 1.4 xargs
      • 1.5 常用find命令
    • 2.grep【擅長在檔案中匹配文本】
      • 2.1 grep,cat,管道符配合使用
      • 2.2 grep,ps,管道符配合使用
      • 2.3 常用grep命令
    • 3.sed【擅長取行】
      • 3.1 sed 格式說明
      • 3.2 s 替換腳本命令
      • 3.3. g,w,p,a,i,c,y,q,r,f,d 腳本命令
      • 3.4 sed實體
    • 4.awk【擅長對行按要求切割】
      • 4.1 wak 格式說明
      • 4.2 awk 欄位變數
      • 4.3 awk 腳本命令使用多個命令
      • 4.4 awk 從檔案中讀取程式
      • 4.5 BEGIN、END關鍵字
      • 4.6 awk 內置變數
      • 4.7 awk 自定義變數和賦值
    • 5.regex

  • find:常用在目錄下精確查找檔案(最擅長找檔案)
  • grep:常用來做全域資料的查詢定位(最擅長文本過濾)
  • sed:常用來做行資料增刪改查(最擅長取行)
  • awk:常用來做列資料切分與提取(最擅長取列)

1.find【擅長在目錄下找檔案】

find 命令用來在指定目錄下查找檔案

語法:find path -option

進階:find path -option [-print][ -exec command] {} \;

注意:{} 表示查詢的結果,

1.1 常用查詢選項option

-name: 根據名稱匹配

-iname: 忽略大小寫

# 例如:查找當前目錄下以log為結尾的檔案:
$ find ./ -name '*log'

-user: 根據所屬與的組進行查詢

# 例如:查當前路徑下,屬于sichuan的檔案:
$ find . -user sichuan

-type: 根據型別進行查找

  • f  檔案        find ./ -type f
  • d  目錄        find . -type d
  • c  字符設備檔案    find . -type c
  • b  塊設備檔案     find . -type b
  • l   鏈接檔案      find . -type l
  • p  管道檔案      find . -type p
# 例如:查當前路徑下所有檔案
$ find ./ -type f

-size: 根據檔案大小匹配

  • -n  小于 大小為 n 的檔案
  • +n  大于 大小為 n 的檔案
# 查找 /ect 目錄下,小于 10000 位元組的檔案
$ find /etc -size -10000c
# 查找 /etc 目錄下,大于 1M 的檔案
$ find /etc -size +1M

-mindepth n: 從第 n 級目錄開始搜索

# 從/etc 的第三級子目錄開始搜索,
$ find /etc -mindepth 3 -name '*.conf'

-maxdepth n: 表示至多搜索到第 n-1 級子目錄,

#在 /etc 中搜索符合條件的檔案,但最多搜索到2級子目錄,  
$ find /etc -type f -name '*.conf' -size +10k -maxdepthc 2

-regex: 基于正則運算式匹配檔案路徑

-iregex: 基于正則運算式匹配檔案路徑(忽略大小寫)

# 匹配當前目錄下,所有.txt和.pdf檔案,用\轉意
$ find ./ -regex ".*\(\.txt\|\.pdf\)$"

1.2 根據時間戳進行搜索

UNIX/Linux檔案系統每個檔案都有三種時間戳

  • 訪問時間 (-atime/天,-amin/分鐘):用戶最近一次訪問時間,
  • 修改時間 (-mtime/天,-mmin/分鐘):檔案最后一次修改時間,
  • 變化時間 (-ctime/天,-cmin/分鐘):檔案資料元(例如權限等)最后一次修改時間,

-mtime:根據檔案更改時間查找,單位小時

  • -n   n 天以內修改的檔案,
  • +n  n 天以外修改的檔案,
  • n   正好 n天 修改的檔案, 

-mmin: 根據檔案更改時間查找,單位分鐘 

  • -n  n 分鐘以內修改過的檔案
  • +n  n 分鐘之前修改過的檔案
# 查詢 /etc 目錄下30分鐘之前修改過的檔案,  
$ find /etc -mmin +30

# 查詢 /etc 目錄下30分鐘之內修改過的目錄, 
$ find /etc -mmin -30 -type d

# 查詢 /etc 目錄下,5天以內修改 且以 conf 結尾的檔案
$ find /etc -mtime -5 -name '*.conf'

#查詢 /etc 目錄下,10天之前修改,且屬于 sichuan的檔案
find /etc -mtime +10 -user sichuan

1.3 對查找到的檔案如何操作

-print: 列印輸出, 默認的選項,即列印出找到的結果,

-exec: 對搜索到的檔案執行特定的操作,固定的格式為:-exec 'commond' {} ; 注意:{} 表示查詢的結果,

# 搜索 /etc 目錄下的檔案(非目錄),檔案以.conf結尾,且大于10k的檔案 然后將其洗掉,
$ find /etc -type f -name '*.conf' -size +10k -exec rm -f {} \;

# 搜索條件同 例1 一樣,但是不洗掉,只是將其復制到 /root/conf 目錄下
$ find /etc -type f -name '*.conf' -size +10k -exec cp {} /root/conf/ \;

# 將 /data/log/ 目錄下以.log 結尾的檔案,且更改時間在 7 天以上的洗掉,
$ find /data/log -name '*.log' -mtime +7 -exec rm -f \;

-ok-exec 的功能一樣,只是每次操作都會給用戶提示,

邏輯運算子

-a:與 (默認情況查詢條件之間都是 與 的關系)

-o:或

-not | ! 非

#或
$ find . \( -name "*.txt" -o -name "*.pdf" \)
$ find . -name "*.txt" -o -name "*.pdf"

#找出/home下不是以.txt結尾的檔案
$ find /home ! -name "*.txt"

1.4 xargs

xargs: 可以將一個命令的輸出作為引數發送給另一個命令,

??當前目錄搜索所有檔案,檔案內容 包含 “aaa” 的內容

$ find ./ -type f -name "*" | xargs grep "aaa"
./a.txt:aaa
./b.txt:aaa

??統計代碼行數

# 代碼行數統計, grep -v '^$'過濾空白行  wc -l 
$ find ./ -name "*.java"|xargs cat|grep -v ^$|wc -l 

1.5 常用find命令

查找當前目錄下所有.txt檔案并把他們拼接起來寫入到all.txt檔案中

$ find ./ -type f -name "*.txt" -exec cat {} \;> ./all.txt

將30天前的.log檔案移動到old目錄中

$ find . -type f -mtime +30 -name "*.log" -exec cp {} old \;

找出當前目錄下所有.txt檔案并以“File:檔案名”的形式列印出來

$ find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;

因為單行命令中-exec引數中無法使用多個命令,以下方法可以實作在-exec之后接受多條命令

$ -exec ./text.sh {} \;

??要列出所有長度為零的檔案

$ find . -empty

擴充:查找關鍵字出現的行數

Linux cat查看檔案,查找關鍵字(grep),統計(wc -l)

#cat查找關鍵字出現的行數
語法:cat 檔案 | grep 關鍵字 | wc -l
$cat /proc/meminfo |grep Swap | wc -l

Linux系統中的wc(Word Count)命令的功能為統計指定檔案中的位元組數、字數、行數,并將統計結果顯示輸出,
#1.命令格式:
wc [選項]檔案...
#2.命令引數:
-c 統計位元組數,
-l 統計行數,
-m 統計字符數,這個標志不能與 -c 標志一起使用,
-w 統計字數,一個字被定義為由空白、跳格或換行字符分隔的字串,
-L 列印最長行的長度,
-help 顯示幫助資訊
--version 顯示版本資訊

2.grep【擅長在檔案中匹配文本】

grep命令 是一種強大的文本搜索工具,它能使用正則運算式搜索文本,并把匹配的行列印出來(匹配的標紅)

  • 語法:grep [option] pattern file

  • 簡介:常用來做全域資料的查詢定位(最擅長文本過濾)


命令引數:

  • -A<顯示行數>:顯示匹配行及后面n行內容
  • -B<顯示行數>:顯示匹配行及前面n行內容
  • -C<顯示行數>:顯示匹配行及前后n行內容
  • -c:統計匹配成功的行數
  • -e :實作多個選項間的邏輯or 關系 ,或者使用egrep
    • $ egrep '^root|bash$' passwd
    • $ grep -e '^abc' -e 'b$' a.txt
  • -E:擴展的正則表達,相當于egrep
  • -f FILE:從FILE獲取PATTERN匹配
  • -F :相當于fgrep
  • -l:列出檔案內容符合指定的范本樣式的檔案名稱,
  • -L:列出檔案內容不符合指定的范本樣式的檔案名稱
  • -i :字符忽略大小寫
  • -n:顯示匹配的行號
  • -o:僅顯示匹配到的字串
  • -q: 靜默模式,不輸出任何資訊
  • -s:不顯示錯誤資訊,
  • -v:顯示不被pattern 匹配到的行,相當于[^] 反向匹配
    • grep -v '^$' :命令的作用是過濾空白符 空白行:^$
  • -w :只匹配整個單詞,而不是字串的一部分(如匹配’magic’,而不是’magical’),
  • --color:匹配到的關鍵字會高亮顯示
  • \< 和 \> 分別標注單詞的開始與結尾,(類似模糊查詢)
    • grep man * 會匹配 ‘Batman’、’manic’、’man’等
    • grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’
    • grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其他的字串
    • 查詢關鍵字高亮顯示:grep xxx --color=auto

舉例:

$cat test.txt 
aaa
bbbbb
AAAaaa
BBBBASDABBDA

#顯示結果及后兩行資料
$grep -A2 b test.txt
bbbbb
AAAaaa
BBBBASDABBDA

#統計行數
$grep -c aaa test.txt
$cat test.txt | grep -c aaa
2

#實作多個邏輯 or 或
$grep -e AAA -e bbb test.txt
bbbbb
AAAaaa

#忽略大小寫并顯示行號
$cat a.txt | grep -in bbb
2:<font color='red'>bbbbb</font>
4:BBBBASDABBDA

#僅顯示匹配到的字串
$grep -o ASDA test.txt
ASDA

#靜默模式,不顯示
$grep -q aa test.txt

#取反
$grep -v aaa test.txt
bbbbb
BBBBASDABBDA

#匹配整個單詞
$grep -w aaa
aaa

#從file獲取PATTERN匹配
$cat grep.txt
aaa
$grep -f grep.txt test
aaa
AAAaaa

# 使用-l選項,找出檔案內容中包含first的檔案名
$ grep -l "first" *.txt
1.txt

# 使用-L選項,找出檔案內容中不包含first的檔案名
$ grep -L "first" *.txt
2.txt
3.txt

# 以leo開頭的行
$ grep '^leo' /etc/passwd

# 以bash結尾的行
$ grep 'bash$' /etc/passwd

# 我們嘗試匹配bin這個“詞”(只包含bin 比匹配sbin這樣的)在正則運算式中,我們通常用尖括號表示一個“詞”
$ grep '\<bin\>' /etc/passwd --color

2.1 grep,cat,管道符配合使用

$ cat test.txt |grep hello  # |管道符,將一個命令的輸出作為另外一個命令的輸

2.2 grep,ps,管道符配合使用

$ ps -ef|grep ssh|grep -v grep  #過濾ssh行程資訊,并去除最后一行的grep資訊

2.3 常用grep命令

查找xxx目錄下所有檔案帶abc的行

$ grep abc /home/sichuan/lihewei/project/daquhua/getMd5Info/*
/home/sichuan/xxx/project/abc/a.txt:abc123
/home/sichuan/xxx/project/abc/b.txt:abcd123

檢索日志,并顯示該條日志的前后N(10)行記錄,并顯示行號(-n)

$ cat 日志檔案 | grep -n -B10 -A10 "關鍵字"

3.sed【擅長取行】

sed 是一種流編輯器,它一次處理一行內容,處理時,把當前處理的行存盤在臨時緩沖區中,稱為“模式空間” ,接著用 sed 命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往螢屏,

  • 簡介:常用來做行資料增刪改查(最擅長取行)

  • 格式:sed [option]... 'script' inputfile

  • 翻譯:sed [選項] [腳本命令] 檔案名

3.1 sed 格式說明

格式:sed [option]... 'script' inputfile

選項【option】:

  • -n 不輸出模式空間內容到螢屏,即不自動列印
  • -e 多點編輯
  • -f /PATH/SCRIPT_FILE: 從指定檔案中讀取編輯腳本
  • -r 支持使用擴展正則運算式
  • -i 直接編輯檔案(慎用)
  • -i.bak 備份檔案并原處編輯

script 地址范圍(選擇第幾行)

  1. 不給地址:對全文進行處理

  2. 單地址:
    #: 指定的行,$:最后一行
    /pattern/:被此處模式所能夠匹配到的每一行

  3. 地址范圍:
    #,#
    #,+#
    /pat1/,/pat2/
    #,/pat1/

  4. ~:步進
    1~2 奇數行
    2~2 偶數行

編輯命令:

  • d 洗掉模式空間匹配的行,并立即啟用下一輪回圈
  • p 列印當前模式空間內容,追加到默認輸出之后(匹配成功的內容追加到文本最后)
  • a []text1 在指定行后面追加文本,支持使用\n實作多行追加
  • i []text 在行前面插入文本
  • c []text 表示把選定的行改為新的文本
  • w /path/somefile 保存模式匹配的行至指定檔案
  • r /path/somefile 在指定的行后插入xx文本中所有內容
  • q 截止到選定的 script 地址時命令終止
  • = 為模式空間中的行列印行號
  • ! 模式空間中匹配行取反處理
  • s///:查找替換,支持使用其它分隔符,s@@@,s###

s///替換標記:【flags 標記】

#格式 1:
$sed ‘s///’ example.txt
#格式 2:
$sed ‘s@@@’ example.txt
  • 數字 1~512 同一行中第幾次出現,例如s/a/x/2,能匹配上的只有 aaa 中間的a,數字代表第二次出現

  • g 選擇的行內全域替換(否則匹配行內第一個)

  • p 顯示替換成功的行

  • w /PATH/TO/SOMEFILE 將替換成功的行保存至檔案中

  • & 用正則運算式匹配的內容進行替換;

  • \n 選中的行內匹配第 n 個子串,該子串之前在 pattern 中用 () 指定,

  • \ 轉義(轉義替換部分包含:&、\ 等),


3.2 s 替換腳本命令

格式:sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile;

解釋:

  • address-range:地址串列,表示從哪個地方開始執行,如:1,3 表示第1行到第 3 行;

  • pattern-range:樣式串列,表示從哪個匹配串開始,如:/Jane/,表示從行中包含字串 Jane 的行開始執行

  • s:表示要執行替換命令(substitute);

  • originalstring:需要被替換的字串 ;

  • replacement-strings:替換后的字串;

  • substitute-flags:可選替換標志符,

注意:如果沒有[address-range|pattern-range],默認選擇全文進行替換

  • d表示洗掉
  • $表示行尾
  • ^表示開頭
  • \s空白符正則
  • \s*表示連續空格的字串

案例:【sed 'script' inputfile`】

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#1. 把第一行的 John 替換成 lili 字串
$ sed '1 s/John/lili/' example.txt
101,lili Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#2. 把第2~5行的 Manager 替換成 lili
$ sed '2,5 s/Manager/lili/' example.txt
101,John Doe,CEO
102,Jason Smith,IT lili
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler lili

#3. 把 John 所在字串行當中的 CEO 替換成 XXX
$ sed '/John/ s/CEO/XXX/' example.txt
101,John Doe,XXX
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#4. 從第四行而且包含字串‘Ram’的行中,把 Developer 字串替換成 XXX
$ sed '4,/Ram/ s/Developer/XXX/' example.txt
101,John Doe,XXX
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#5. 如果沒有 address-range 和 pattern-range,那么就會把每一行碰到的第一個匹配字串給替換掉
$ sed 's/1/AAA/' example.txt
AAA01,John Doe,CEO
AAA02,Jason Smith,IT Manager
AAA03,Raj Reddy,Sysadmin
AAA04,Anand Ram,Developer
AAA05,Jane Miller,Saler Manager

#6 s///后的數字標記 1,2,3 把要匹行中第 n 個符合條件的匹配串替換成我們想要的字串
# 把每一行第二個匹配的1,進行替換
$ sed 's/1/AAA/2' example.txt
10AAA,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#7 $ 將 origin-string 替換到 replace-string 
$ sed 's/John/[&]/' example.txt
101,[John] Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 用文本模式指定行區間
$ grep demo /etc/passwd
demo:x:502:502::/home/Samantha:/bin/bash
# 用正斜線將要指定的 pattern 封起來,sed 會將該命令作用到包含指定文本模式的行上,
# 在包含'demo'的行中,進行s替換
$ sed '/demo/s/bash/csh/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
demo:x:502:502::/home/demo:/bin/csh
...

3.3. g,w,p,a,i,c,y,q,r,f,d 腳本命令

g 全域替換

#g 全域標志會把遇到的所有的滿足條件的字串給替換掉
$ sed 's/1/AAA/g' example.txt
AAA0AAA,John Doe,CEO
AAA02,Jason Smith,IT Manager
AAA03,Raj Reddy,Sysadmin
AAA04,Anand Ram,Developer
AAA05,Jane Miller,Saler Manager

w 輸出到文本

#把每行碰到第一個字串 John 替換成 lili 字串,并寫入 output.txt 中,不寫數字默認就是第一個匹配到的
$ sed 's/1/AAA/1w output.txt' example.txt
$ cat output.txt
AAA01,John Doe,CEO

p 標記會輸出修改過的行

#3. -n -p (-n 選項會禁止sed輸出,但p標記會輸出修改過的行)
$ sed -n 's/1/AAA/2p' example.txt
10AAA,John Doe,CEO

a 命令追加行(在匹配內容后面追加)

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 在行尾追加 xxx
$ sed '$ a xxx' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager
xxx

# 在文本匹配處增加多行
$ sed '/Jason/ a \aaa\bbb' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
aaabbb
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

使用 i 命令插入行(在匹配內容前面插入)

$ sed '2 i xxx' example.txt
101,John Doe,CEO
xxx
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

使用 c 命令修改所在行

$ sed '/Jason/ c xxx' example.txt
101,John Doe,CEO
xxx
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

使用 y 命令作字符轉換

$ cat a.txt
abcdef
1234

$ sed 'y/abc/ABC/' a.txt
ABCdef
1234

使用 q 命令終止執行

#示例:sed '3 q' input-file 執行完第3行后終止
#格式:sed '/Anand/ q' input-file匹配到 Anand 行后退出

$ sed '3 q' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin

$ sed '/Jason/ q' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager

r 將檔案中的內容插入到匹配位置后

# sed 命令會將 filename 檔案中的內容插入到 address 指定行的后面,比如說:
$ cat data12.txt
This is an added line.
This is the second added line.
$ sed '3r data12.txt' data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an added line.
This is the second added line.
This is line number 4.

# 如果你想將指定檔案中的資料插入到資料流的末尾,可以使用 $ 地址符,例如:
$ sed '$r data12.txt' data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is an added line.
This is the second added line.

f 插入并使用sh腳本

$ cat test.txt
<html>
<title>First Wed</title>
<body>
h1Helloh1
h2Helloh2
h3Helloh3
</body>
</html>
#使用正則表示式給所有第一個的h1、h2、h3添加<>,給第二個h1、h2、h3添加</>
$ cat sed.sh
/h[0-9]/{
    s//\<&\>/1
    s//\<\/&\>/2
}
$ sed -f sed.sh test.txt
<h1>Hello</h1>
<h2>Hello</h2>
<h3>Hello</h3>

d 洗掉腳本命令

#當和指定地址一起使用時,洗掉命令顯然能發揮出大的功用,可以從資料流中洗掉特定的文本行,
#通過行號指定,比如洗掉 data6.txt 檔案內容中的第 3 行:
$ cat data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
$ sed '3d' data6.txt
This is line number 1.
This is line number 2.
This is line number 4.

#或者通過特定行區間指定,比如洗掉 data6.txt 檔案內容中的第 1、3行:
$ sed '2,3d' data6.txt
This is line number 4.

#或者通過特殊的檔案結尾字符,比如洗掉 data6.txt 檔案內容中第 3 行開始的所有的內容:
$ sed '3,$d' data6.txt
This is line number 1.
This is line number 2.

3.4 sed實體

查看某段時間內的日志:

# sed -n ‘/開始時間日期/,/結束時間日期/p’ xx.log | grep “包含的關鍵字”
$ sed -n ‘/2018-06-21 14:30:20/,/2018-06-21 16:12:00/p’ log.txt | grep ‘keyword’

# 時間里有/的要用轉意字符\轉意
$ sed -n '/2022\/10\/26 14:27:16/,/2022\/10\/26 18:27:16/p' wrapper.log | grep 'POST'

# 對日志模糊查詢
$ sed -n ‘/2022-10-24 21*/,/2022-10-24 22*/p’ xx.log

# 日志匯出
$ sed -n ‘/2019-10-24 22:16:21/,/2019-10-21 20:16:58/p’ all.log > yoyo.log

將文本的前三位數截取出來,并加上大括號,去掉后面的全部內容

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#1. 正則運算式的()前要加轉義符\   \(\)
#2. (^[0-9]*\),.* 解釋:以0-9開頭的0個或多個元素 逗號 .*任意字符出現0次或多次
#3. \1 解釋:\1指的是轉義括號所捕獲的字符
$ sed 's@\(^[0-9]*\),.*@{\1}@g' example.txt
$ sed 's/\(^[0-9]*\),.*/{\1}/g' example.txt
{101}
{102}
{103}
{104}
{105}

# 深入了解  \n 
$ echo 'abcabcabc' | sed 's@\(ab\)c@\1@'
ababcabc
$ echo 'abcabcabc' | sed 's@\(ab\)c@\1@g'
ababab
$ echo 'abcabcabc' | sed 's@\(ab\)\(c\)@\1d\2@g'
abdcabdcabdc

去掉注釋行和空行 ( ^$ 表示空行)

# -i直接編輯檔案 -e多點編輯
$ sed -i -e 's/^#.*//g; /^$/d'

行首添加#

#1,3行首添加#
sed 1,3 s/^/#/g
#12345
#23456
#34567
45678

4.awk【擅長對行按要求切割】

4.1 wak 格式說明

? awk 命令也是逐行掃描檔案(從第 1 行到最后一行),尋找含有目標文本的行,如果匹配成功,則會在該行上執行用戶想要的操作;反之,則不對行做任何處理,

簡介: 常用來做列資料切分與提取(最擅長取列)

語法:

awk [選項] '腳本命令' 檔案名

awk [選項] '匹配規則{執行命令}' 檔案名

語法解釋:

? 1. ’匹配規則‘:表示從哪個地方開始執行,如:1,3 表示第1行到第 3 行;或者寫觸發事件:BEGIN、END

? 2. 整個‘腳本命令’是用單引號' '括起,而其中的 ‘執行命令’ 部分需要用大括號{}

? 3. 如果沒有指定 ’執行命令‘,則默認會把匹配的行輸出;如果不指定’匹配規則‘,則默認匹配文本中所有的行

選項 含義
-F fs 指定以 fs 作為輸入行的分隔符,awk 命令默認分隔符為空格或制表符,
-f file 從腳本檔案中讀取 awk 腳本指令,以取代直接在命令列中輸入指令,
-v var=val 在執行處理程序之前,設定一個變數 var,并給其設備初始值為 val,

舉例:

test.txt有N個空白行,就會輸出N個Blank line,

$ awk '/^$/ {print "Blank line"}' test.txt  

以:分割,篩選以/root開頭,顯示結果每行的第一個欄位和第七個阻斷

$ awk -F ":" '/^root/{print $1,$7}' test.txt

4.2 awk 欄位變數

awk 的主要特性之一是其處理文本檔案中資料的能力,awk 在讀取一行文本時會用預定義的欄位分隔符劃分每個資料欄位,它會自動給一行中的每個資料元素分配一個變數,

默認情況下,awk 會將行按指定要求切割后分配如下變數:

  • $0 代表整個文本行;
  • $1 代表文本行中的第 1 個資料欄位;
  • $2 代表文本行中的第 2 個資料欄位;
  • $n 代表文本行中的第 n 個資料欄位,

在 awk 中,默認的欄位分隔符是任意的空白字符,

# awk 程式讀取文本檔案,只顯示第 1 個資料欄位的值:
$ cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.
$ awk '{print $1}' data2.txt
One
Two
Three
# 可以用 -F 選項手動指定 例如:
$ awk -F'#''{print $1}' data2.txt

4.3 awk 腳本命令使用多個命令

awk 允許將多條命令組合成一個正常的程式,只要在命令之間放個;分號即可,例如:

$ echo "My name is Rich" | awk '{$4="Christine"; print $0}'
My name is Christine

#也可以分開寫

$ awk '{
> $4="Christine"
> print $0}'
My name is Christine

注意:此例中因為沒有在命令列中指定檔案名,awk 程式需要用戶輸入獲得資料,因此當運行這個程式的時候,它會一直等著用戶輸入文本,此時如果要退出程式,只需按下 Ctrl+D 組合鍵即可,

4.4 awk 從檔案中讀取程式

跟 sed 一樣,awk 允許將腳本命令存盤到檔案中,然后再在命令列中參考,比如:

$ cat awk.sh
{print $1 "'s home directory is " $6}

$ awk -F: -f awk.sh /etc/passwd
root's home directory is '/root
bin's home directory is '/bin
daemon's home directory is '/sbin
adm's home directory is '/var/adm
lp's home directory is '/var/spool/lpd

注意:在程式檔案中,也可以指定多條命令,只要一條命令放一行即可,之間不需要用分號,

4.5 BEGIN、END關鍵字

語法:awk '[BEGIN]{..}{..}[END{..}]' file

BEGIN和END顧名思義,在awk中,BEGIN只在開始處理之前運行一次,END只在結束處理之后運行一次,非常適合用在做一些前置操作時使用,通常求和類初始化值、設定分隔符等經常會用,

和 BEGIN 關鍵字相對應,END 關鍵字允許我們指定一些腳本命令,awk 會在讀完資料后執行它們,例如:

$ cat data3.txt
Line 1
Line 2
Line 3
$ awk 'BEGIN {print "The data3 File Contents:"}{print $0}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3

#1.求和
awk 'BEGIN{sum=0}{sum+=$1}END{print sum}' file
#2.求均值
awk 'BEGIN{sum=0}{sum+=$1}END{print sum/NR}' file
#NR為總記錄數
#3.求最大值
awk 'BEGIN{max=0} {if($1 > max)max = $1} END{print max}'

可以看到,當 awk 程式列印完檔案內容后,才會執行 END 中的腳本命令,

舉例:統計檔案行數

awk 'END{print NR}' file...

4.6 awk 內置變數

awk有許多內置變數用來設定環境資訊,這些變數可以被改變,下面給出了最常用的一些變數,

  • ARGC 命令列引數個數

  • ARGV 命令列引數排列

  • ENVIRON 支持佇列中系統環境變數的使用

  • FILENAME awk瀏覽的檔案名

  • FNR 瀏覽檔案的記錄數

  • FS 設定輸入域分隔符,等價于命令列 -F選項

  • NF 瀏覽記錄的域的個數(切割)

  • NR 已讀的記錄數

  • OFS 輸出域分隔符

  • ORS 輸出記錄分隔符

  • RS 控制記錄分隔符

實體:

# 統計/etc/passwd:檔案名,每行的行號,每行的列數,對應的完整行內容:
$ awk -F ':' '{print"filename:" FILENAME ",NR:" NR", NF:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,NR:1,NF:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,NR:2,NF:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,NR:3,NF:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,NR:4,NF:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

#使用printf替代print,可以讓代碼更加簡潔,易讀
$ awk  -F ':' '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}'/etc/passwd

注意:命令結尾的路徑是絕對路徑

# 列印以'#'分隔后,數量=5的 第一段字符
$ awk -F '#' 'NF==5 {print $1}' test

# 看命令自己翻譯
$ awk -F '#' 'NF>=4 && NF<=5 {print $1}' test

4.7 awk 自定義變數和賦值

除了awk的內置變數,awk還可以自定義變數,

# 統計/etc/passwd的賬戶人數,$0列印一整行
$ awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is  40

count是自定義變數,之前的action{}里都是只有一個print,其實print只是一個陳述句,而action{}可以有多個陳述句,以;號隔開,

# 這里沒有初始化count,雖然默認是0,但是妥當的做法還是初始化為0
$ awk 'BEGIN {count=0;print "[start]user count is ",count} {count=count+1;print $0;} END{print "[end]user count is ",count}' /etc/passwd

[start]user count is  0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is  40

統計某個檔案夾下的檔案占用的位元組數

$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ", size}'
[end]size is  8657198

#如果以M為單位顯示:
$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ", size/1024/1024,"M"}'
[end]size is  8.25889 M

注意:ls -l,會羅列出所有檔案的資訊,默認以空格分個,$5正好是位元組大小,統計不包括檔案夾的子目錄

5.regex

正則就是用有限的符號,表達無限的序列

5.1 匹配字符

  • . 匹配任意單個字符,不能匹配空行
  • [] 匹配指定范圍內的任意單個字符,[0-9a-zA-Z]、[a-zA-Z]、 [A-Z]、[a-z]
  • ^[0-9] 以0-9開頭
  • [0-9]$ 以0-9結尾
  • [^] 取反

5.2 配置次數

  • ***** 匹配前面的字符任意次,包括0次,貪婪模式:盡可能長的匹配
  • .* 任意長度的任意字符,不包括0次
  • ? 匹配其前面的字符0 或 1次
  • \+ 匹配其前面的字符至少1次
  • {n} 匹配前面的字符n次
  • {m,n} 匹配前面的字符至少m 次,至多n次
  • {,n} 匹配前面的字符至多n次
  • {n,} 匹配前面的字符至少n次

注意:{}在正則運算式中需要轉意,而{}()不需要,

5.3 出現位置

  • ^ 行首錨定,用于模式的最左側
  • $ 行尾錨定,用于模式的最右側
  • ^PATTERN$,用于模式匹配整行
  • ^$ 空行
  • ^[[:space:]].*$ 空白行
  • < 或 \b 詞首錨定,用于單詞模式的左側
  • > 或 \b 詞尾錨定;用于單詞模式的右側

5.4 轉意字符

\是轉移字符,其后面的字符會代表不同的意思,常用的轉意字符:

轉移字符 含義
\n 匹配換行符
\r 匹配回車符
\t 匹配制表符
\w 匹配任意一個數字、字母、下劃線
\W 匹配非數字、字母、下劃線的任意一個字符(特殊字符)
\d 匹配數子字符0~9
\D 匹配非數字字符 !0~9
\\ 匹配\

5.5 選擇運算式

正則中用|來表示分組,a|b表示匹配a或者b的意思

123|456|789 // 匹配 123 或 456 或 789

5.6 分組與參考

參考的語法是 \數字,數字代表參考前面第幾個捕獲分組(括號中的匹配),注意非捕獲分組不能被參考

\ 表示轉意字符

<([a-z]+)><\/\1> // 可以匹配 `<span></span>` 或 `<div></div>`等

實體:

$ cat c.txt 
abc
abcc
abccc
abcccc
aaa
ac
yyycc

# \? 匹配其前面的字符0或1次(匹配的是ABC出現的次數)
$ grep "abc\?" c.txt
abc
abcc
abccc
abcccc
abccccc

# \+ 匹配其前面的字符至少1次(匹配的是ABC出現的次數)
$ grep "abc\+" c.txt
abc
abcc
abccc
abcccc
abccccc

$ grep "c\+" c.txt 
abc
abcc
abccc
abcccc
abccccc
ac
yyycc

#前面字符至少出現過3次
$ grep "c\{3,\}" c.txt
abccc
abcccc
abccccc

#以a開頭
$ grep "^a" c.txt
abc
abcc
abccc
abcccc
abccccc
aaa
ac

#以c結尾
$ grep "c$" c.txt
abc
abcc
abccc
abcccc
abccccc
ac
yyycc

#匹配y開頭,c結尾的字符  \是轉意字符
$ grep "\<y.*c\>" c.txt
yyycc

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546301.html

標籤:Java

上一篇:關于JAVA泛型陣列型別擦除引發的問題及解決方案

下一篇:Python從零到壹丨詳解影像平滑的兩種非線性濾波方法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more