linux shell腳本攻略 第二章 命令之樂 cat,find,tr,sort,uniq,split等

目錄

1. 使用cat進行拼接

2.錄製並回放終端會話

3.find命令

4. xargs命令

5. tr命令進行轉換

6.校驗和與覈實(md5)

7.加密工具與散列

8.排序,唯一與重複

9.臨時文件命名

10.分割文件和數據

11.根據擴展名切分文件名

12.批量重命名和移動

13.交互輸入自動化

14.使用並行進程加速命令執行


 

介紹常用命令grep,sed,find等命令。

1. 使用cat進行拼接

cat本身表示拼接(concatnate)。

  • 將標準輸入與文件內容拼接
Ian>ls |cat  - out.txt 
func.sh
out.txt
prp.sh
script.sh
     1	func.sh
     2	out.txt
     3	script.sh
  • 擺脫多餘的空白行:cat -s

可將多行空白行壓縮成一行

Ian>cat space.txt 
l1


l2
l3



l4
Ian>cat -s space.txt 
l1

l2
l3

l4
  • 將製表符顯示成^I:cat -T file
  • 顯示行號:cat -n
  • 所有參數:

-n 或 --number:由 1 開始對所有輸出的行數編號。

-b 或 --number-nonblank:和 -n 相似,只不過對於空白行不編號。

-s 或 --squeeze-blank:當遇到有連續兩行以上的空白行,就代換爲一行的空白行。

-v 或 --show-nonprinting:使用 ^ 和 M- 符號,除了 LFD 和 TAB 之外。

-E 或 --show-ends : 在每行結束處顯示 $。

-T 或 --show-tabs: 將 TAB 字符顯示爲 ^I。

-A, --show-all:等價於 -vET。

-e:等價於"-vE"選項;

-t:等價於"-vT"選項;

2.錄製並回放終端會話

使用script和scriptplay命令

  • 錄製:script -t 2> timing.log -a output.session  使用exit結束
  • 回放:scriptreplay timing.log output.session 自動回放錄製的命令
Ian>script -t 2> timing.log -a output.session
Script started, file is output.session
Ian>ls
func.sh         out.txt  script.sh  tab.py
output.session  prp.sh   space.txt  timing.log
Ian>history |grep ll
    6  ll
    8  ll
   10  ll
   11  echo hello !
   15  ll
   18  ll
   21  ll
   25  ll
   27  ll
   29  ll
   30  sudo ./vmware-install.pl 
   78  sudo apt install vim  
   98  ll && PATH="/home/ian/Documents/:$PATH"
  135  ll
  175  ll
  207  history |grep ll
Ian>exit
exit
Script done, file is output.session
Ian>scriptreplay timing.log output.session 
Ian>ls
func.sh         out.txt  script.sh  tab.py
output.session  prp.sh   space.txt  timing.log
Ian>history |grep ll
    6  ll
    8  ll
   10  ll
   11  echo hello !
   15  ll
   18  ll
   21  ll
   25  ll
   27  ll
   29  ll
   30  sudo ./vmware-install.pl 
   78  sudo apt install vim  
   98  ll && PATH="/home/ian/Documents/:$PATH"
  135  ll
  175  ll
  207  history |grep ll
Ian>exit
exit

3.find命令

  • 列出當前目錄下所有的文件和文件夾

find .

find . -print0

-print用於確認分隔符,默認'\n',如果使用print0,則用'\0'作爲分隔符

Ian>find . -print
.
./tab.py
./out.txt
./timing.log
./space.txt
./script.sh
./func.sh
./prp.sh
./output.session
Ian>find . -print0
../tab.py./out.txt./timing.log./space.txt./script.sh./func.sh./prp.sh./output.session
  • 根據文件名或者正則搜索

find path -name

find path -iname:忽略大小寫

find path \( -name "*.txt" -o -name "*.pdf" \):匹配多個條件

find path -path "*/ian/*":匹配整個路徑

find . ! -name "*.txt*":找出不包含txt的文件

Ian>ls
func.sh  output.session  out.txt  prp.sh  script.sh  space.txt  tab.py  timing.log
Ian>find . -name "*out*"
./out.txt
./output.session
Ian>find . -name "*Out*"

Ian>find . -iname "*Out*"
./out.txt
./output.session
Ian>find . \( -name "*txt*" -o -name "*sh*" \)
./out.txt
./space.txt
./script.sh
./func.sh
./prp.sh
Ian>mkdir f1
Ian>touch f1/a.log
Ian>find . -path "*/f1/*"
./f1/a.log
Ian>find . ! -name "*.txt"
.
./f1
./f1/a.log
./f1/b.log
./tab.py
./timing.log
./script.sh
./func.sh
./prp.sh
./output.session


  • 根據深度查找

find . -maxdepth 1:最深路徑,1爲當前路徑

find . -mindepth 2:最淺路徑,從這個深度開始查找,忽略比這個深度淺的

Ian>ls
f1  func.sh  output.session  out.txt  prp.sh  script.sh  space.txt  tab.py  timing.log
Ian>touch dep.txt
Ian>touch f1/dep.txt
Ian>find . -maxdepth 1 -name "*dep*"
./dep.txt
Ian>find . -mindepth 2 -name "*dep*"
./f1/dep.txt
  • 按照文件類型匹配

find . -type d:只查出目錄

類型參數:普通文件f  文件夾文件d  符號文件l  字符設備c  塊設備b

  • 按照文件時間匹配

-atime:訪問時間,天爲單位

-mtime:內容修改時間,天爲單位

-ctime:權限或者所有權最後一次改變的時間,天爲單位

其中+2代表2天之外,-3代表3天之內

amin,mmin,cmim分別是分鐘爲單位的訪問,內容修改,權限改變時間

Ian>find . -mmin +800
./out.txt
./script.sh
./func.sh
./prp.sh
Ian>find . -atime -2
.
./f1
./f1/a.log
./f1/dep.txt
./f1/b.log
./tab.py
./out.txt
./timing.log
./space.txt
./script.sh
./func.sh
./dep.txt
./prp.sh
./output.session

-newer:找出比一個文件更新(修改時間更近的文件)

Ian>find . -newer dep.txt -type f
./f1/dep.txt
  • 按照文件大小匹配

find . -size +2k:找出大於2k的文件

  • 刪除匹配的文件:-delete

find . -name "*.txt" -delete:刪除所有txt文件

  • 按照文件權限和所有權匹配

-perm 644:按照權限匹配

-user ian:按照用戶匹配

  • find後執行命令或者動作

使用exec可以在find之後執行命令

find . -name "*.sh" -exec cat {} \; > all_txt.txt

這個命令將所有.sh的文件拼接到一個文件中。其中每個找到的文件都被{}代替,所以需要分號";"來分割每個命令

跳過特定目錄

  • 使用prune命令(不好用)
Ian>find . \( -path ./f1 -prune \) -o \( -type f \)
./f1
./tab.py
./out.txt
./timing.log
./space.txt
./all_txt.txt
./script.sh
./func.sh
./dep.txt
./prp.sh

4. xargs命令

接收數據流命令。可以將數據重新格式化。

  • 格式化數據

多行轉單行,單行轉多行:

-n表示一行的元素個數,然後劃分爲多行

Ian>cat xars.txt 
1 2 3
4 5 6
7
Ian>cat xars.txt |xargs 
1 2 3 4 5 6 7
Ian>cat xars.txt |xargs -n 4
1 2 3 4
5 6 7
  • 自定義分隔符:-d
Ian>echo "12v34v56v78"|xargs -d v
12 34 56 78
  • 給腳本傳參

echo "12v34v56v78"|xargs -n 1 -d v ./do.sh:每次向腳本傳一個字符串,執行多次腳本

echo "12v34v56v78"|xargs -n 1 -d v -I {} ./do.sh -p {} -h:腳本有多個參數傳遞時,僅替換傳入的參數。{}爲循環執行

  • 和find搭配使用

find . -name "*.txt" -type f -print0|xargs -0 rm -f :刪除所有txt文件

find source_path -name "*.c" -type f -print0|xargs -0 wc -l:統計c語言的代碼行數

5. tr命令進行轉換

tr命令介紹:https://www.jb51.net/article/103892.htm

  • 轉換字符:
Ian>echo "Hello World!" | tr 'A-Z' 'a-z' 
hello world!
Ian>cat sum.txt | echo $[ $(tr "\n" "+") 0]
15

可以使用字符類轉換: 

Ian>echo "123he4l4lo6" | tr '[:lower:]' '[:upper:]'
123HE4L4LO6

字符類包括:

\NNN 八進制值的字符 NNN (1 to 3 爲八進制值的字符)

\\ 反斜槓

\a Ctrl-G 鈴聲

\b Ctrl-H 退格符

\f Ctrl-L 走行換頁

\n Ctrl-J 新行

\r Ctrl-M 回車

\t Ctrl-I tab鍵

\v Ctrl-X 水平製表符

CHAR1-CHAR2 從CHAR1 到 CHAR2的所有字符按照ASCII字符的順序

[CHAR*] in SET2, copies of CHAR until length of SET1

[CHAR*REPEAT] REPEAT copies of CHAR, REPEAT octal if starting with 0

[:alnum:] 所有的字母和數字

[:alpha:] 所有字母

[:blank:] 水平製表符,空白等

[:cntrl:] 所有控制字符

[:digit:] 所有的數字

[:graph:] 所有可打印字符,不包括空格

[:lower:] 所有的小寫字符

[:print:] 所有可打印字符,包括空格

[:punct:] 所有的標點字符

[:space:] 所有的橫向或縱向的空白

[:upper:] 所有大寫字母

 

  • 刪除字符:tr -d
Ian>echo "123he4l4lo6" | tr -d "0-9"
hello
  • 字符補集:tr -c
Ian>echo "123he4l4lo6" | tr -d -c "0-9"
123446

上面可以將不在補集中的字符都刪掉

  • 壓縮字符:tr -s
Ian>echo "shell      is     good script"|tr -s " "
shell is good script

6.校驗和與覈實(md5)

用於文件完整性測試的特定密鑰就是校驗和。

  • 生成md5:
Ian>md5sum all_txt.txt 
5c8b5885df01c5cf0b0eeb2b628579df  all_txt.txt
  • 校驗md5:
Ian>md5sum all_txt.txt > all_txt.md5
Ian>md5sum -c all_txt.md5 
all_txt.txt: OK

sha-1也是常用的校驗算法,用法與md5相同,把md5sum改爲sha1sum即可

  • 校驗目錄
Ian>md5deep -rl f1/
d41d8cd98f00b204e9800998ecf8427e  f1/a.log
d41d8cd98f00b204e9800998ecf8427e  f1/b.log
d41d8cd98f00b204e9800998ecf8427e  f1/dep.txt

7.加密工具與散列

用於防止數據遭未經授權的訪問。

  • crypt

crypt PASSWORD <input_file >output_file:加密

crypt PASSWORD -d <encrypted_file >output_file:解密

  • gpg

gpg -c file:加密

gpg file.gpg:解密

  • base64

base64 filename > output_file:加密

base64 -d file > output_file:解密

8.排序,唯一與重複

排序:sort

詳細:https://www.cnblogs.com/delav/p/9956819.html

唯一:uniq,要求文件必須是排序好的

  • sort基本用法

對多個文件排序:sort f1 f2 > sort.txt,默認是首字母排序

按照數字順序排序:sort -n f1

逆序排序:sort -r

按照月份排序:sort -M

合併兩個排序過的文件:sort -m f1 f2

找出已排序文件中不同的行:sort f1 f2|uniq

檢查是否排序過:sort -C f; if [ $? -eq 0]; then echo 1; else echo 0;fi

  • sort常用方法

按照鍵值列排序:sort -k 2,按照第二列排序

按照鍵值列排序,切指定列的範圍:sort -k 2,3 f,按照列的2-3個字符來排序

忽略空格僅考慮數字字母作爲鍵值:sort -bd f。其中-b爲忽略空格,-d爲只奧綠空格和字母數字

生成\0作爲分隔符的文件用於和xargs一起使用:sort -z

  • uniq用法

通過消除重複內容,用於找出唯一的行,也可以找出重複行

顯示唯一的行:sort f1 | uniq

統計各行出現的次數:sort f1 |uniq -c找出重複行:sort f1 |uniq -d

Ian>sort xars.txt wargs.txt > sort.txt
Ian>cat sort.txt 
1
1 2 3
2
2
3
4
4 5 6
7
Ian>sort xars.txt wargs.txt|uniq
1
1 2 3
2
3
4
4 5 6
7
Ian>sort xars.txt wargs.txt|uniq -c
      1 1
      1 1 2 3
      2 2
      1 3
      1 4
      1 4 5 6
      1 7
Ian>sort xars.txt wargs.txt|uniq -d
2

忽略前n個字符:sort -s

指定鍵值的最大字符數:sort -w

Ian>cat data.txt 
u:01:gnu
d:04:linux
u:02:bash
u:01:hack
Ian>sort data.txt | uniq -s 2 -w 2
d:04:linux
u:01:gnu
u:02:bash

9.臨時文件命名

mktemp可以創建臨時文件或者目錄

Ian>mktemp
/tmp/tmp.jjRu3Hun5g
Ian>mktemp -d
/tmp/tmp.1wTP2dnulQ
Ian>mktemp -u
/tmp/tmp.EMrUeB1h6C
Ian>mktemp test.XXX
test.Pim

10.分割文件和數據

split命令

  • 基本使用

-b:按照大小分割,可以按照G,M,k,c,w分割,例如split -b 100k file

-d:分割後的文件以數字爲後綴

-a:指定後綴長度

-l:按照長度分割

  • 常用方法

指定文件名前綴:split file prefix

Ian>rm -f x*
Ian>split -b 100k -d -a 2 vmware-install.pl test
Ian>ll
total 456
drwxr-xr-x 2 ian ian   4096 Apr 11 23:34 ./
drwxr-xr-x 4 ian ian   4096 Apr 11 23:26 ../
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test00
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test01
-rw-r--r-- 1 ian ian  22224 Apr 11 23:34 test02
-rwxr-xr-x 1 ian ian 227024 Apr 11 23:27 vmware-install.pl*
Ian>split -l 2000 vmware-install.pl 
Ian>ll
total 684
drwxr-xr-x 2 ian ian   4096 Apr 11 23:36 ./
drwxr-xr-x 4 ian ian   4096 Apr 11 23:26 ../
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test00
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test01
-rw-r--r-- 1 ian ian  22224 Apr 11 23:34 test02
-rwxr-xr-x 1 ian ian 227024 Apr 11 23:27 vmware-install.pl*
-rw-r--r-- 1 ian ian  57202 Apr 11 23:36 xaa
-rw-r--r-- 1 ian ian  60775 Apr 11 23:36 xab
-rw-r--r-- 1 ian ian  66419 Apr 11 23:36 xac
-rw-r--r-- 1 ian ian  42628 Apr 11 23:36 xad

csplit可以根據文件內容分割

11.根據擴展名切分文件名

${VAR%.*},刪除位於%右側的通配符所匹配的字符串。使用%對字符串進行匹配,非貪婪,從右向左找出匹配的最短結果,%%用於貪婪匹配,從右向左找出匹配的最長結果

Ian>f2="h1.h2.jpg"
Ian>echo ${file%.*}
Ian>echo ${f2%.*}
h1.h2
Ian>echo ${f2%%.*}
h1

${VAR#*.},刪除位於#右側的通配符所匹配的字符串。使用#對字符串進行匹配,非貪婪,從左向右出匹配的最短結果,%%用於貪婪匹配,從左向右找出匹配的最長結果

Ian>echo ${f2#*.}
h2.jpg
Ian>echo ${f2##*.}
jpg

12.批量重命名和移動

  • rename命令可以批量重命名文件

rename 's/jpg/JPG/g' *.jpg

rename 'y/a-z/A-Z/' *

Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:21 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 a.jpg
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 b.jpg
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 c.jpg
Ian>rename 's/jpg/JPG/g' *.jpg
Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:30 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 a.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 b.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 c.JPG
Ian>rename 'y/a-z/A-Z/' *
Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:32 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 A.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 B.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 C.JPG

13.交互輸入自動化

  • 發送交互式腳本進行自動化交互
#!/bin/bash
#inter.sh
read -p "Enter number:" no;
read -p "Enter name:" name;
echo "num:$no, name$name"


Ian>echo -e "1\nian" | bash inter.sh
num:1, name:ian

使用except自動化交互

#!/usr/bin/expect
#auto_expect.sh
spawn bash inter.sh
expect "Enter number:"
send "1\n"
expect "Enter name:"
send "ian\n"
expect eof


Ian>./auto_expect.sh 
spawn bash inter.sh
Enter number:1
Enter name:ian
num:1, name:ian
Ian>vim auto_expect.sh 

注意,頭部使用#!/usr/bin/expect

14.使用並行進程加速命令執行

使用&後臺執行

for file in list_file;

do

    md5sum $file &

done

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章