2014-10-08 161 views
0

我正在尋找一種簡單的方法,在允許嵌入空間的情況下使用awk打印特定字段。用AWK忽略嵌入空格

樣品:Field1 Field2 "Field Three" Field4

我希望能夠以相當於做awk '{print $3}'但得到「第三場」作爲一個單一的領域而不是兩個。

更新:更具體地說,我需要得到後來的領域不是3美元,但#3的空間是什麼搞砸了。 $ 3中引號之間的空格數量是可變的。即使並非所有字段都被引用,我只是希望能夠將引號之間的內容視爲單個字段。所以,如果在引號之間,忽略空格作爲字段分隔符。

回答

1

你可以做到這一點,如果雙引號始終存在:

awk -F\" '{print $2}' 

具體來說,我告訴awk的字段都用雙引號分開,此時您需要的部分是現成的場2.

如果您需要獲得在隨後的場,你可以分割的空間行的剩餘部分,並得到一個新的數組,說田F[],像這樣:

awk -F\" '{split($3,F," ");print $2,F[1],F[2]}' file 

Field Three Field4 Field5 

假設你的文件是這樣的:

Field1 Field2 "Field Three" Field4 Field5 Field6 
+0

是的,這給我確切的場3,但不能得到後期的領域。 – 2014-10-09 20:45:12

+0

我沒有意識到你想要後期的領域。我已經添加了一種應對方式,所以請再看一下。 – 2014-10-09 21:13:33

+0

太棒了。這給我一個我需要的技巧,並能夠將其調整爲真實的數據。 (27個字段,引用空格的倍數。)[對不起,是一個偏執的安全人員。]謝謝你的幫助! – 2014-10-10 19:07:12

0

馬克·瑟特查的回答是好,但如果你事先不知道你有多少個嵌入式引號將無法正常工作(它不各執空間了)。

我砍死了一起(這顯然可以提高):

gawk -v FIELD=2 '{ a=$ FIELD; if (substr(a, 0, 1) == "\"") { gsub(/^\"/, "", a); s=a; for (i = FIELD + 1; i <= NF; i++) { a=$ i; nbSub=gsub(/\"$/, "", a); s = s " " a; if (nbSub > 0) { break } } print(s) } }' <<<'allo "hello world" bar' 

我會建議使用的東西比呆呆地看着這個別人(可能考慮與解析你的shell變量IFS領域?)。

附錄:如上所述,這不是真正適合這項工作的工具。例如,您可以使用-v FIELD =指定第一個字段,但是它會基於AWK的分隔符計算字段(嵌入的空間仍會計數)。

+0

謝謝大家的意見,但這些都不能幫助我。 也許我的總體目標還不夠清楚。 (試圖保持簡單的問題。) 更具體地說,我需要得到後來的領域不是3美元,但在3美元的空間是什麼東西搞砸了。 $ 3中引號之間的空格數量是可變的。即使並非所有字段都被引用,我只是希望能夠將引號之間的內容視爲單個字段。所以,如果在引號之間,忽略空格作爲字段分隔符。 有沒有其他想法?我希望這顯然更困難。 – 2014-10-09 20:38:28

1

基於this,在gawk也許你可以使用類似

awk 'BEGIN{FPAT = "([^ ]+)|(\"[^\"]+\")"}{print $3}' input.txt 

輸出:

"Field Three" 

它可能需要更多的工作來獲取適合您的需求完全。

我覺得需要gawk 4+,https://lists.gnu.org/archive/html/info-gnu/2011-06/msg00013.html

+0

這似乎與基本{print $ 3}的效果完全相同。我得到#3的前1/2。 – 2014-10-09 20:44:36

+0

@ Chris-9090,它是'gawk'特定的,需要版本4或更高版本。你在使用GNU awk('gawk')還是其他一些實現?試試'awk --version'來查看你正在使用哪個實現。爲了這個工作,輸出應該看起來像'GNU Awk 4.1.0,API:1.0' – Ashkan 2014-10-10 06:47:34

1

解析CSV可以是一個棘手的業務。我喜歡使用適當的CSV解析模塊的語言。例如紅寶石,解析給定的線,使用空格作爲列分隔符,以及默認雙引號引號字符:

ruby -rcsv -ne 'row = CSV.parse_line($_, {:col_sep=>" "}); puts row[2]' <<END 
Field1 Field2 "Field Three" Field4 
END 
Field Three 
+0

對不起,我沒有在這個系統上訪問Ruby。 – 2014-10-09 20:44:16

0

馬克·瑟特查的解決方案爲我工作最好的:

awk -F\" '{split($3,F," ");print $2,F[1],F[2]}' file