[英]reuse command output multiple times in bash script
我有一個 bash 腳本,它運行幾個類似的查找命令並將 output 讀入變量:
f_list=`find /foo -name bar | sort`
f_number=`find /foo -name bar | wc -l`
f_first=`find /foo -name bar | sort | head -n 1`
所有這些都按預期工作。
假設“查找”命令很昂貴(時間方面),是否有一種巧妙的方法可以為其他結果重新使用其中一個結果?
我嘗試過(但失敗了)是:
f_list=`find /foo -name bar | sort`
f_number=`echo "$f_list" | wc -l`
f_first=`echo "$f_list" | head -n 1`
這不起作用,但我希望它顯示我想要實現的目標。
似乎將結果放入變量中會破壞原始 output 的某些格式,當再次發送到其他命令時會破壞內容。
有什么聰明的方法可以實現我想要的嗎?
編輯
我創建了一個可以重新創建的完整工作示例。 在我的工作目錄中,我有一個文件夾“foo”,其中包含 3 個文件“bar1”、“bar2”、“bar3”。
find_result=`find ./foo -type f -iname "bar*" | sort`
find_count1=`echo "$find_result" | wc -l`
echo "$find_result"
echo $find_count1
find_count2=`find ./foo -type f -iname "bar*" | wc -l`
find ./foo -type f -iname "bar*"
echo $find_count2
結果是預期的
./foo/bar1
./foo/bar2
./foo/bar3
3
./foo/bar3
./foo/bar2
./foo/bar1
3
但是當結果為空時(我修改了搜索條件,什么也沒找到)
find_result=`find ./foo -type f -iname "bor*" | sort`
find_count1=`echo "$find_result" | wc -l`
echo "$find_result"
echo $find_count1
find_count2=`find ./foo -type f -iname "bor*" | wc -l`
find ./foo -type f -iname "bor*"
echo $find_count2
兩個結果不同(注意“1”前面的空結果行)
1
0
因此,我認為罪魁禍首是 echo 命令中的額外換行符。 因此我刪除了它(注意第二行中的“-n”):
find_result=`find ./foo -type f -iname "bor*" | sort`
find_count1=`echo -n "$find_result" | wc -l`
echo "$find_result"
echo $find_count1
find_count2=`find ./foo -type f -iname "bor*" | wc -l`
find ./foo -type f -iname "bor*"
echo $find_count2
這解決了空結果的問題
0
0
但是現在當有結果時,“wc -l”計數錯誤,所以
find_result=`find ./foo -type f -iname "bar*" | sort`
find_count1=`echo -n "$find_result" | wc -l`
echo "$find_result"
echo $find_count1
find_count2=`find ./foo -type f -iname "bar*" | wc -l`
find ./foo -type f -iname "bar*"
echo $find_count2
產量在
./foo/bar1
./foo/bar2
./foo/bar3
2
./foo/bar3
./foo/bar2
./foo/bar1
3
所以問題是一個換行符,我認為必須有一個簡單的解決方案,以避免空和非空查找結果之間的差異。 我有一種錯過了一些非常簡單的東西的感覺。
使用變量重用find
的 output 應該可以工作。 也許您的文件名中有反斜杠會被echo
解釋(盡管默認情況下不應該發生這種情況)。 如果是這樣,則使用printf %s "$f_list"
代替。 但如果沒有完整的可驗證示例,我們無法確定。
但是,在這種特定情況下,您也可以切換到以下命令,如果沒有文件匹配,這也是安全的,並且在某些文件具有多行文件名的非常不尋常的情況下也是安全的。
shopt -s globstar dotglob nullglob
list=(/foo/**/bar)
number=${#list[@]}
first=${list[0]}
另一種方法是使用臨時文件。 那將是這樣的:
temp=$(mktemp /tmp/prefixXXXXXXXXXXX)
find /foo -name bar | sort > $temp
f_number=`wc -l $temp`
f_first=`head -n 1 $temp`
rm -f $temp
使用數組存儲find -print0 | sort -z
返回的null
分隔列表 find -print0 | sort -z
:
#!/usr/bin/env bash
# map null delimited output of command-group into the f_list array
mapfile -t f_list < <(find /foo -name bar -print0 | sort --zero-terminated)
# Number of entries in the f_list array
f_number=${#f_list[@]}
# First entry of the f_list array
f_first=${f_list[0]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.