Linux
列印行中每個大寫字母都以不同字母開頭的行
我有這段文字:
FOUR MILLION, EIGHT HUNDRED AND FIFTY-SEVEN THOUSAND, FIVE HUNDRED AND THIRTEEN innovating FORTY-NINE MILLION, ONE HUNDRED AND EIGHTY THOUSAND, TWO HUNDRED AND FORTY-EIGHT championed FORTY-SEVEN MILLION, NINE HUNDRED AND FIFTY-TWO THOUSAND, EIGHT HUNDRED AND SIX swashbuckling NINE HUNDRED AND SIXTY-ONE THOUSAND, SIX HUNDRED AND THIRTY-ONE sprinklers FORTY-TWO MILLION, TWO HUNDRED AND SIXTY-SIX THOUSAND, THREE HUNDRED AND SEVENTY-TWO furloughs SEVEN MILLION, FOUR HUNDRED AND SEVENTEEN THOUSAND, FOUR HUNDRED AND FORTY-TWO panicky THREE HUNDRED AND SEVENTY-NINE THOUSAND, FIVE HUNDRED AND TWENTY-EIGHT anchovies FIVE MILLION, EIGHT HUNDRED AND FIFTY-NINE THOUSAND, FOUR HUNDRED AND SIXTY-FOUR excesses ............
如何使用
grep
或sed
列印大寫字母行的每個單詞都以不同字母開頭的行?例如:
FIFTY THOUSAND, NINE HUNDRED AND EIGHTEEN FOURTEEN THOUSAND, SEVEN HUNDRED AND NINETY-EIGH
您可以使用正則表達式對輸入進行掃描並獲得所需的輸出。
我們告訴
grep
尋找一個大寫單詞,它的第一個字元在該行的下方但僅在另一個大寫單詞的開頭。由於這意味著至少有一個這樣的匹配,但我們不希望這樣-v
的匹配,所以我們反轉匹配的意義以獲得所需的輸出。編輯:根據@they 的觀察,它被修改為查找大寫單詞。
grep -v '\<\([A-Z]\)[A-Z]\{1,\}\>.*\<\1[A-Z]\{1,\}\>' file
解決此類問題的首要任務是為工作選擇正確的工具。在這個問題中,我們需要計算每個單詞的首字母在一行中出現的次數。兩者都以不擅長計數
grep
而sed
著稱,至少它們本身是不擅長計數的,而awk
更像是一種通用程式語言。如果我們想使用任何單一的工具來解決任務,awk
可能會更適合。awk '{ delete count for (i = 1; i <= NF; ++i) { ch = substr($i,1,1) if (ch == toupper(ch) && count[ch]++) next } print }' file
該程式碼計算每行上所有單詞的初始大寫字母的出現次數(單詞是由空格分隔的子字元串)。我們將計數保存在關聯數組
count
中,由數據中的字母索引。一旦我們第二次遇到其中一個首字母,我們就會丟棄該行。我們以這種方式列印我們不丟棄的每一行。
此程式碼只關心單詞的第一個字元是否為大寫。要測試全部大寫的單詞的第一個字元,請改用以下命令:
awk '{ delete count for (i = 1; i <= NF; ++i) if ($i != toupper($i) && count[substr($i,1,1)]++) next print }' file
下一個問題是理解程式碼。您現在已經獲得了程式碼,並且它可以工作,但您可能不知道為什麼。更重要的是,您可能不知道如何修改它以做一些稍微不同的事情,或者如果它在您發現的某些極端情況下突然失敗,如何糾正它。
您可以通過查找
awk
手冊中的每一位作為開始來更好地了解程式碼。然後,當你不明白我為什麼delete count
在那個特定的地方而不是其他地方寫的時候,你可以問另一個關於這個的問題,或者更好的是,對程式碼進行試驗並註意它以什麼特定方式破壞。