我有一個帶有單詞和正數的文本文件,由一些空格分隔,例如,在字符串「number」之後總結數字
A dog has a ball number 49 number 34 number A
Cats number 58
...
我想總結字符串「數字」後面出現的所有數字。如果在一個字符串「數字」之後不是一個數字,那麼它並不重要。
例如,在這種情況下,答案將是49 + 34 + 58,即141
。
我有一個帶有單詞和正數的文本文件,由一些空格分隔,例如,在字符串「number」之後總結數字
A dog has a ball number 49 number 34 number A
Cats number 58
...
我想總結字符串「數字」後面出現的所有數字。如果在一個字符串「數字」之後不是一個數字,那麼它並不重要。
例如,在這種情況下,答案將是49 + 34 + 58,即141
。
awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s+0 }' test.txt
awk讀取文件,每行一行。對於每一行,執行標記爲{}
的塊。塊可以通過以下條件來保護:正則表達式,...,和BEGIN
和END
,它們分別對於第一行和最後一行是「真」的。
這意味着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
您可以通過設置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
+1,RS =數字是一個聰明的解決方案! –
有一個警告:RS只使用第一個字符,所以RS = number與RS = nothing相同; http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_19.html –
@RudolfMühlbauer:對於舊的沙發來說,這是正確的。原來的awk和nawk,但不適用於更新的版本,例如mawk和gawk,如果它比一個字符長,則將RS視爲正則表達式。 – Thor
我使用Ubuntu的,我真的不知道該如何處理這個,而不是由我自己暴力破解。但我有一個非常大的文件。 – John