詳解shell指令碼(五) 玩轉find查詢

2021-08-15 18:10:04 字數 3307 閱讀 4258

find查詢

#find命令有乙個選項-iname會忽略字母的大小寫

find . \( -name "*.txt" -o -name "*.pdf" \) -print

#\(以及\)會讓中間的內容視為乙個整體 -o 匹配多個條件中的乙個

find . ! -name "*.txt" -print #否定引數"!"

find命令在使用時會遍歷所有的子目錄。我們可以採用深度選項-maxdepth和 -mindepth來限制find命令遍歷的目錄深度。使用下列命令將find命令向下的最大深度限制為1:find . -maxdepth 1 -name 「f*」 -print 列印出深度距離當前目錄至少兩個子目錄的所有檔案:

find . -mindepth 2 -name 「f*」 -print

單位是天,-表示小於,+表示大於

find . type -f -atime -7 -print #最近7天被訪問的

find . type -f -atime 7 -print #7天前訪問的檔案

find . type -f -atime +7 -print #訪問時間超過7天

#單位是分鐘的 amin mmin cmin

find . -type f -name 「*.swp」 -delete

find . -type f -perm 664 -print 列印許可權是644的檔案

-user user 找到某個特定使用者所擁有的檔案

在這個命令中, {}是乙個與 -exec選項搭配使用的特殊字串。對於每乙個匹配的檔案,{}會被替換成相應的檔名。例如, find命令找到兩個檔案test1.txt和test2.txt,其所有者均為slynux,那麼find就會執行:chown slynux {}

有時候我們並不希望對每個檔案都執行一次命令。我們更希望使用檔案列表作為命令引數,這樣就可以少執行幾次命令了。如果是這樣,可以在exec中使用+來代替;。

$ find . -type f -name 「*.c」 -exec cat {} \;>all_c_files.txt

將給定目錄中的所有c程式檔案拼接起來寫入單個檔案all_c_files.txt

我們無法在-exec引數中直接使用多個命令。它只能夠接受單個命令,不過我們可以耍乙個小花招。把多個命令寫到乙個shell指令碼中(例如command.sh),然後在-exec中使用這個指令碼

以上命令列印出不包括在.git目錄中的所有檔案的名稱(路徑)

玩轉xargs

我們可以用管道將乙個命令的stdout(標準輸出)重定向到另乙個命令的stdin(標準輸入)。例如:

cat foo.txt | grep 「test」

但是,有些命令只能以命令列引數的形式接受資料,而無法通過stdin接受資料流。在這種情況下,我們沒法用管道來提供那些只有通過命令列引數才能提供的資料。

xargs命令應該緊跟在管道操作符之後,以標準輸入作為主要的源資料流。它使用stdin並通過提供命令列引數來執行其他命令。

xargs命令把從stdin接收到的資料重新格式化,再將其作為引數提供給其他命令xargs可以作為一種替代,其作用類似於find命令中的 -exec。

xargs有乙個選項-i,可以提供上面這種形式的命令執行序列。我們可以用-i指定替換字串,這個字串在xargs擴充套件時會被替換掉。如果將-i與xargs結合使用,對於每乙個引數,命令都會被執行一次。

cat args.txt | xargs -i {} ./cecho.sh -p {} -1

-p arg1 -1 #

-p arg2 -1 #

-p arg3 -1 #

#-i {}指定了替換字串。對於每乙個命令引數,字串{}都會被從stdin讀取到的引數替換掉。

正規表示式-regex

e-mail位址通常採用[email protected]這種形式,所以可以將其一般化為[a-z0-9]+@[a-z0-9]+.[a-z0-9]+。符號+ 指明在它之前的字元類中的字元可以出現一次或多次。

find . -type f -user root -exec chown slynux {} \;
在這個命令中,{}是乙個與 -exec選項搭配使用的特殊字串。對於每乙個匹配的檔案,{}會被替換成相應的檔名。

find . -type f -name "*.c" -exec cat {} \;>all_c_files.txt

#執行指令碼

-exec ./commands.sh {} \;

find devel/source_path \( -name ".git" -prune \) -o \( -type f -print \)

# instead of \( -type -print \),而是選擇需要的過濾器

( -name 「.git」 -prune )的作用是用於進行排除,它指明了 .git目錄應該被排除在外,而( -type f -print )指明了需要執行的動作。這些動作需要被放置在第二個語句塊中(列印出所有檔案的名稱和路徑)。

#! /bin/bash

#檔名:cecho.sh

echo $*'#'

cat args.txt | xargs -i {} ./cecho.sh -p {} -l

-p arg1 -l #

-p arg2 -l #

-p arg3 -l #

統計源**目錄中所有c程式檔案的行數

find source_code_dir_path f -name "*.c" -print0 | xargs -0 wc -l

#-0 將\0作為輸入定界符

結合stdin,巧妙運用while語句和子shell

xargs只能以有限的幾種方式來提供引數,而且它也不能為多組命令提供引數。要執行包含來自標準輸入的多個引數的命令,有一種非常靈活的方法。包含while迴圈的子shell可以用來讀取引數,然後通過一種巧妙的方式執行命令

cat files.txt | (while read arg; do cat $arg; done )

#等同於 cat files.txt | xargs -i {} cat {}

用tr進行轉換

tr只能通過stdin(標準輸入),而無法通過命令列引數來接受輸入。它的呼叫格式如下: tr [options] set1 set2

如果兩個字符集的長度不相等,那麼set2會不斷重複其最後乙個字元,直到長度與set1相同。如果set2的長度大於set1,那麼在set2中超出set1長度的那部分字元則全部被忽略。

shell指令碼學習(五)

1 統計檔案的行數 單詞數 字元數 1 行數 wc l file cat file wc l 2 單詞數 wc w file cat file wc w 3 統計字元數 wc c file cat file wc c 4 不跟任何引數時,三者都列印,列印順序為行數 單詞數 字元數 wc file h...

Shell指令碼函式詳解

二 呼叫函式的方法 三 函式作用的範圍 1.將命令序列按格式寫在一起 2.可方便重複使用命令數列 function 函式名 for a in 遍歷使用者給定的位置引數 docheckpid a 呼叫checkpid函式,檢查對應的程序是否在執行 if eq 0 then 根據函式的返回值做判斷 ec...

詳解shell指令碼 n

在寫指令碼的時候,總是搞不懂 的區別,這次寫乙個總結,把它掌握牢固 和test 兩者是一樣的,在命令列裡test expr和 expr 的效果相同。test的三個基本作用是判斷檔案 判斷字串 判斷整數。支援使用 與或非 將表示式連線起來。test中可用的比較運算子只有 和 兩者都是用於字串比較的,不...