2012-10-12 39 views
1

我有一個帶有單詞和正數的文本文件,由一些空格分隔,例如,在字符串「number」之後總結數字

A dog has a ball number 49  number 34 number A 
Cats number 58 
... 

我想總結字符串「數字」後面出現的所有數字。如果在一個字符串「數字」之後不是一個數字,那麼它並不重要。

例如,在這種情況下,答案將是49 + 34 + 58,即141

+0

我使用Ubuntu的,我真的不知道該如何處理這個,而不是由我自己暴力破解。但我有一個非常大的文件。 – John

回答

4
awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s+0 }' test.txt 

awk讀取文件,每行一行。對於每一行,執行標記爲{}的塊。塊可以通過以下條件來保護:正則表達式,...,和BEGINEND,它們分別對於第一行和最後一行是「真」的。

這意味着awk會爲每一行執行第一個塊(因爲它是無保護的)。

此外,awk並沒有真正的類型系統 - 所有字符串。但是你可以在字符串上使用算術 - 在這種情況下,它們被神奇地轉換爲數字。如果你對字符串進行算術運算,它們不是數字,它們的計算結果爲'0'。 這意味着:「asdf」+ 1 = 1; 2 + 4 = 6; 「asdf」+ 0 = 0;

變量不必聲明 - 缺省爲空字符串,其值爲'0'。

awk的下一個awesome是它自動將當前輸入行分割成字段。可以指定字段分隔符,但缺省爲空格。單個字段可以通過$1,$2,... $NF來訪問,即NF是字段的數量。 $0是完整輸入行的內容。

在那裏你有它:你看當前行的所有'領域'。所有字段的數值(字符串爲0)在變量s中累計。讀完所有內容後(END),打印總和。

編輯:這可能方便地工作,但並沒有真正回答這個問題,因爲它不考慮'數字' - 對不起。

甲修正:

awk '{ for (i = 1; i <= NF; i++) if ($i == "number") {s = s+$(++i)} }; END { print s+0 }' test.txt 

這種方式,它也導致141,用於輸入這樣的:

10狗具有球數49號34號甲 貓1000號58

+0

如果沒有太多的麻煩,你能否簡單地解釋一下你的代碼的作用? – John

+0

非常感謝! – John

2

您可以通過設置number作爲記錄分隔符來分隔awk的輸入:

awk -v RS=number '{ sum += $1 } END { print sum }' infile 

這裏有一個grep的,coreutils的和bc替代:

(<infile grep -Eoi 'number[[:blank:]]+[0-9]+' \ 
| tr -s '[:blank:]' | cut -d' ' -f2 | head -c -1 \ 
| tr '\n' '+'; echo 
) | bc 

輸出:

141 
+0

+1,RS =數字是一個聰明的解決方案! –

+0

有一個警告:RS只使用第一個字符,所以RS = number與RS = nothing相同; http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_19.html –

+0

@RudolfMühlbauer:對於舊的沙發來說,這是正確的。原來的awk和nawk,但不適用於更新的版本,例如mawk和gawk,如果它比一個字符長,則將RS視爲正則表達式。 – Thor

相關問題