2017-08-29 59 views
0

我正在處理文本文件並添加由其他列的某些組件組成的列。要求刪除空格和撇號的新要求,我不確定完成此任務的最有效方法。使用awk打印沒有撇號或空格的新列

該文件的內容可以通過以下腳本創建:

content=(
    john smith   thomas  blank 123 123456 10 
    jane smith   elizabeth blank 456 456123 12 
    erin "o'brien"  margaret  blank 789 789123 9 
    juan "de la cruz" carlos  blank 1011 378943 4 
) 
# put this into a tab-separated file, with the syntactic (double) quotes above removed 
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "${content[@]}" >infile 

這是我現在,但它不能刪除空格和撇號:

awk -F "\t" '{OFS="\t"; print $1,$2,$3,$5,$6,$7,$6 tolower(substr($2,0,3)); }' infile > outfile 

這將引發錯誤「子第三個參數不是可變的對象「,這是有道理的,因爲我試圖處理輸出而不是輸入,我猜。

awk -F "\t" '{OFS="\t"; print $1,$2,$3,$5,$6,$7,$6 sub("'\''", "",tolower(substr($2,0,3))); }' infile > outfile 

有沒有一種方法,我可以在較低的情況下打印列6和第2列的部分的組合,同時還能從輸出去掉空格和撇號到新列?最糟糕的情況是,我可以用我的第一個命令創建一個新文件,並用新的awk命令處理輸出,但是我希望一次完成就可以。

+0

是否有一個理由,你想'awk'這個,而不是使用(說)bash內置功能? –

+0

提供一個獨立的示例並不需要有人提供他們自己的'infile'來測試也是有幫助的。 –

+0

我沒有awk作爲要求,但它似乎是一個合乎邏輯的解決方案,因爲我正在處理一個帶有製表符分隔內容的文件,我不希望將更改應用於所有列。如果你有另一個不使用awk的解決方案,我肯定會接受其他選擇。 –

回答

0

第二種方法是關閉,但對於操作順序:

awk -F "\t" ' 
    BEGIN { OFS="\t"; } 
    { 
    var=$2; 
    sub("['\''[:space:]]", "", var); 
    var=substr(var, 0, 3); 
    print $1,$2,$3,$5,$6,$7,$6 var; 
    } 
' 
  • 分配要修改一個變量的內容讓該變量就地進行修改。
  • 要刪除的字符應刪除之前採取子字符串,因爲否則您縮短您的3個字符的子字符串。
+0

你忘了照顧雙引號,所以它打印789123「ob,它應該是789123obr。 –

+0

@mlambrichs,...這個代碼在給出你提供的輸入時絕對會打印'78123obr',因爲這個輸入中唯一的引號你只指定了「撇號」 - 那些是單引號,所以,不,我沒有忘記任何東西 –

+0

你在吠叫錯誤的樹;;-)我剛剛檢查了你的解決方案,這是所有的,我檢查了OP的早期版本的輸入,我的不好, –

0

這是一個猜測,因爲你沒有提供預期的輸出,但這是你想要做的?

$ cat tst.awk 
BEGIN { FS=OFS="\t" } 
{ 
    abbr = $2 
    gsub(/[\047[:space:]]/,"",abbr) 
    abbr = tolower(substr(abbr,1,3)) 
    print $1,$2,$3,$5,$6,$7,$6 abbr 
} 

$ awk -f tst.awk infile 
john smith thomas 123  123456 10  123456smi 
jane smith elizabeth  456  456123 12  456123smi 
erin o'brien margaret  789  789123 9  789123obr 
juan de la cruz  carlos 1011 378943 4  378943del 

注意的方式在' -enclosed awk腳本代表'與八進制\047(這將繼續當你移動你的腳本文件,如果工作/,不像你仗着"'\''"它只能從命令行起作用),並且awk中的字符串,數組和字段從1開始,而不是從0開始,因此您的substr(..,0,3)錯誤,awk將0的無效起始位置視爲您已使用第一個有效開始這是1的位置。

"sub third parameter is not a changeable object"錯誤你得到的是因爲sub()修改你怎麼稱呼它與作爲第三個參數,但你和一個文本字符串(的tolower(substr(...))輸出)調用它的對象,你不能修改一個字符串 - 嘗試sub(/o/,"","foo"),如果您使用var="foo"; sub(/o/,"",var),您將得到相同的錯誤,因爲您可以修改變量的內容,因此這是有效的。

+0

我們的兩個答案的輸出之間的差異 - 我的排放'789123obr',而不是'789123ob' –

+0

是的,因爲你在substr()調用之前刪除''',之後我會這樣做。我只是遵循OP在代碼中的含義(在substr()調用後刪除''') - 因爲他沒有發佈預期的輸出idk,這是正確的。 –

+1

對。如果OP *希望輸出中少於三個字符的子字符串,我會感到非常驚訝。 –