2016-09-28 32 views
0

假設有一個目錄「」它包含幾個文件:如何在bash腳本中存儲程序的NUL輸出?

ls foo: 
1.aa 2.bb 3.aa 4.cc 

現在在bash腳本,我希望計算「FOO」具有特定後綴的文件數和顯示他們,例如:

SUFF='aa' 
FILES=`ls -1 *."$SUFF" foo` 
COUNT=`echo $FILES | wc -l` 
echo "$COUNT files have suffix $SUFF, they are: $FILES" 

的問題是:如果SUFF='dd'$COUNT也等於1。谷歌後,我發現的原因是當SUFF='dd'$FILES是一個空字符串,不是一個程序的空輸出,它將被認爲有一行wc。 NUL輸出只能通過管道傳遞。所以一個解決方案是:

COUNT=`ls -1 *."$SUFF" foo | wc -l` 

但這會導致ls命令被執行兩次。所以我的問題是:有沒有更好的方法來實現這一目標?

+0

的文件名以'foo'結束?你可以給一個這樣的樣本名稱嗎?你想遞歸搜索子目錄嗎? – Inian

+0

foo是目錄。文件名以aa,bb,cc結尾。不需要搜索子目錄。 – xlwang

回答

2
$ shopt -s nullglob 
$ FILES=(*) 
$ echo "${#FILES[@]}" 
4 
$ FILES=(*aa) 
$ echo "${#FILES[@]}" 
2 
$ FILES=(*dd) 
$ echo "${#FILES[@]}" 
0 
$ SUFFIX=aa 
$ FILES=(*"$SUFFIX") 
$ echo "${#FILES[@]}" 
2 
$ SUFFIX=dd 
$ FILES=(*"$SUFFIX") 
$ echo "${#FILES[@]}" 
0 
+0

很好的解釋! – 123

+3

@ 123:這很有趣,我沒有寫。你最近去過眼科醫生嗎? –

+0

是否有一種簡單的方法逐個輸出文件的內容? – xlwang

0

如果你只需要文件的數量,我會實際使用find爲:

find '/path/to/directory' -mindepth 1 -maxdepth 1 -name '*.aa' -printf '\n' | wc -l 

這是更可靠的,因爲它正確處理與換行符的文件名。這種工作方式是find爲每個匹配文件輸出一個空行。

編輯:如果你想保持在一個陣列的文件列表,你可以使用水珠:

GLOBIGNORE=".:.." 
shopt -s nullglob 
FILES=(*aa) 
COUNT=${#arr[@]} 
echo "$COUNT" 
+0

但我也希望稍後在腳本中輸出這些文件的名稱。 – xlwang

+1

@Inian你是什麼意思? – redneb

+0

@Inian它確實是因爲它們只爲每個文件名輸出一個換行符,而不是實際的文件名 – 123

0

你也可以試試這個;

#!/bin/bash 
SUFF='aa' 
FILES=`ls -1 *."$SUFF" foo` 
FILENAMES=`echo $FILES | awk -F ':' '{print $2}'` 
COUNT=`echo $FILENAMES | wc -w` 
echo "$COUNT files have suffix $SUFF, they are: $FILENAMES" 

如果你的腳本插入echo $FILES,輸出foo: 1.aa 2.aa 3.aa所以

的awk -F ':' '{打印$ 2}' 從$ FILES變量

wc -w打印變得1.aa 2.aa 3.aa字計數

0

原因是選項nullglob在默認情況下未設置在bash中:

如果未找到匹配的文件名,並且未啓用shell選項nullglob,則該字保持不變。如果設置了nullglob選項,並且找不到匹配項,則會刪除該詞。

所以,剛纔設置的選項了nullglob,並再次運行你的代碼:

shopt -s nullglob 
SUFF='aa' 
FILES="$(printf '%s\n' foo/*."$SUFF")" 
COUNT="$(printf '%.0s\n' foo/*."$SUFF" | wc -l)" 
echo "$COUNT files have suffix $SUFF, they are: $FILES" 

或者更好的是:

shopt -s nullglob 
suff='aa' 
files=(foo/*."$suff") 
count=${#file[@]} 
echo "$count files have suffix $suff, they are: ${files[@]}" 
+0

Thx。但是,如果文件名包含\ n,則可能會失敗。 – xlwang

+0

@xlwang好的,解決了。 '%.0s \ n'每個文件只打印一行。 – sorontar