Awk
如何用 awk 替換 sed 和 wc?(計算目錄中的名稱)
我想計算文件夾中元素的數量。我想到了
function lsc { /bin/ls -l $1 | sed 1d | wc -l }
但後來我想起
awk
人們是如何減少這種管道的,去掉多餘grep
的 s 和sed
s。那麼,你會怎麼做awk
呢?
不需要
ls
,或.sed
_wc``awk
如果您只是想計算一個模式擴展到多少個名稱,那麼您可以使用
set -- * echo "$#"
該
set
命令將位置參數($1
、$2
等)設置為與*
模式匹配的名稱。這會自動將特殊變數$#
設置為設置位置參數的數量,即匹配給定模式的名稱數量。在
bash
具有命名數組的外殼中或外殼中,您可以使用names=(*) echo "${#names[@]}"
這類似地工作,但將
names
數組的元素設置為由模式擴展產生的名稱*
。變數擴展${#names[@]}
將是names
數組中元素的數量。這樣做的一個問題是,如果模式與任何內容都不匹配,它將保持未擴展狀態,因此您得到的計數為 1(即使目錄為空)。
bash
要在shell中解決此問題,請將nullglob
shell 選項設置為shopt -s nullglob
. 通過設置此 shell 選項,不匹配任何內容的模式將被完全刪除。在
bash
中,如果您還想計算隱藏名稱,請dotglob
使用 設置 shell 選項shopt -s dotglob
。您的函式可能如下所示
bash
:lsc () ( shopt -s nullglob set -- "$1"/* echo "$#" )
注意
( ... )
函式體的使用,以避免nullglob
在呼叫shell中設置。或者,對於
/bin/sh
:lsc () { set -- "$1"/* if [ -e "$1" ] || [ -L "$1" ]; then echo "$#" else echo 0 fi }
這裡的
if
語句確保第一個位置參數是實際文件的名稱,而不是未擴展的模式(由於不匹配任何內容)。(-e
“exists”) 必須為真,我們才能信任$#
. 如果它不是真的,那麼我們另外檢查名稱是否指的是與-L
測試的符號連結。如果這是真的,我們知道模式擴展的第一件事是“死”符號連結(指向不存在文件的符號連結),我們相信$#
這是正確的。如果兩個測試都失敗了,我們知道我們沒有匹配任何東西,因此輸出0
。