的簡單的方法來做到這一點是利用哈希表,其通過bash的4.x和當然的直接支持可在AWK和Perl中找到。如果你沒有散列表,那麼你需要循環兩次:一次收集第二列的唯一值,一次總和。
有很多方法可以做到這一點。這裏有一個不使用awk,sed或perl的樂趣。我在這裏使用的唯一外部工具是剪切,排序和uniq。你甚至可以用更多的努力替換cut
。事實上,第5-9行可能更容易用grep編寫,(grep $kind stock.txt
),但我避免了炫耀bash的力量。
for kind in $(cut -d\; -f 2 stock.txt | sort | uniq) ; do
total=0
while read d ; do
total=$((total+d))
done < <(
while read line ; do
[[ $line =~ $kind ]] && echo $line
done < stock.txt | cut -d\; -f3
)
echo "Total amount for $kind: $total"
done
我們在這裏失去了原始輸出的嚴格排序。你的練習可能是找到一種不這樣做的方法。
討論: 第一行描述了一個使用cut
的簡單流水線的子shell。我們從stock.txt
文件中讀取第三個字段,其中的字段描述爲;
,在此處寫爲\;
,因此shell不解釋它。結果是從stock.txt
換行符分隔的值列表。這通過管道連接到sort
,然後uniq
。這將執行我們的「分組」步驟,因爲管道將輸出第二列中的項目的字母列表,但無論輸入文件中出現了多少次,它都只會列出一個項目。
同樣在第一行是典型的for
循環:對於從子殼產生的每個項目,我們循環一次,將項目的值存儲在變量kind
中。這是分組步驟的另一半,確保每個「總計」輸出行出現一次。
在第二行total
被初始化爲零,因此無論何時啓動新組時,它都會重置。
第三行開始'totaling'循環,其中對於當前的kind
,我們找到其出現的總和。在這裏我們聲明我們將在循環的每次迭代中從標準輸入讀取變量d
。
在第四行實際發生的總數:使用shell arithmatic我們將d
中的值加到total
中的值。
第五行結束while循環,然後描述其輸入。我們使用通過<
的shell輸入重定向來指定循環的輸入,從而指定read
命令來自文件。然後我們使用process substitution來指定該文件實際上是命令的結果。
在第六行上,將提供while-read循環的命令開始。它本身是另一個讀取循環,這次讀入變量line
。在第七行上,測試通過conditional construct執行。這裏我們使用[[
作爲=~
運算符,它是一個模式匹配運算符。我們正在測試$line
是否符合我們目前的$kind
。
在第八行我們結束內同時讀取循環,並指定其輸入來自stock.txt
文件,那麼我們管的整個迴路的輸出,其通過現在是簡單地匹配$kind
,以cut
所有行和指示它僅顯示第三個字段,即數字字段。在第九行,我們結束進程替換命令,其輸出是由kind
指定的組的行中的新行劃定的數字列表。
鑑於總數已知且種類已知,將結果打印到屏幕是一件簡單的事情。
感謝您的誠實。是的,我們很容易得到直接的解決方案,但是如果我們只是爲你做,那麼你就會受到考試時間的影響。但這裏的人很樂意給你一些想法。 – 2010-12-06 17:32:05
嗨拉夫,那是我擔心..考試..哈哈..因此,我需要誠實,並找到自己的解決方案,但我需要你的指導方針,我的課程筆記是非常有限的,缺乏例子。 – bashington02 2010-12-06 17:34:27
您可以使用哪些工具有限制嗎? awk可以很容易地做到這一點...... – 2010-12-06 17:36:03