2013-09-05 58 views
4

我努力做到以下幾點:無法分開分號分隔行AWK

  1. 逐行讀取一個文件行。
  2. 的每一行都具有以下結構:field1;field2;field3
  3. 使用awk到每個字段的分離,然後處理這些字段進一步

代碼段我的是:

while read l 
do 
n=`echo ${l} | awk --field-separator=";" '{print NF}'` 
field1=`echo ${l} | awk --field-separator=";" '{print $1}'` 
field2=`echo ${l} | awk --field-separator=";" '{print $2}'` 
field3=`echo ${l} | awk --field-separator=";" '{print $3}'` 
echo ${n} ${field1} ${field2} ${field3} 
done < temp 

其中temp僅包含以下行:

xx;yy;zz 

我得到的命令行上的答案是:

1 xx;yy;zz 

我不知道我理解這個輸出。任何解釋都會很好,因爲它可以用於其他文件。我在Mac上工作,而此代碼在bash腳本中使用awk

+0

我得到了預期的輸出:'3 xx yy zz'您正在使用哪個版本的'awk'? – hek2mgl

+0

'awk --version'結果爲「awk version 20070501」 – Sriram

+0

我有'GNU Awk 3.1.8'。嘗試使用'gawk 3'在機器上執行該腳本以查看它是否真的是版本問題 – hek2mgl

回答

3

你的awk不知道什麼--field-separator=";"意思,所以當你這樣做:

awk --field-separator=";" '{print $1}' 

你的awk依然採用了空間的默認FS,等1 $包含您的整個輸入線,而$ 2和$ 3空。使用-F';'來設置FS。

你是如何寫你想要的腳本的方式。如果您告訴我們更多關於「處理每個領域」的內容,我們可以幫助您。

+1

爲什麼這麼居高臨下? '--field-separator =「;」'在我的機器上工作,不是問題。而且awk手冊頁甚至指定:'-F fs或--field-separator fs,使用fs作爲輸入字段分隔符(FS預定義變量的值)。' 至於關閉標記:我同意,但也許你可以提供更好的解決方案,就像其他人一樣。 – jmiserez

+0

什麼居高臨下?不管你的awk做了什麼或不接受,那是OP的問題,如果你建議像其他答案所說的任何類型的shell循環都是更好的解決方案,那麼你也是這樣(請參閱[爲什麼要使用shell循環處理文本被認爲是壞習慣](http://unix.stackexchange.com/questions/169716/why-is-using - shell-loop-to-process-text-considered-bad-practice)),我不能提供更好的解決方案,因爲OP尚未完全描述問題。 –

7

爲什麼awk當你可以在純bash中做到這一點?

while IFS=';' read -r field1 field2 field3; do 
    echo "Field1: $field1" 
    echo "Field2: $field2" 
    echo "Field3: $field3" 
done < file.txt 

或者,如果你不知道的場數:

while IFS=';' read -ra fields; do   
    echo "Number of fields: ${#fields[@]}" 
    echo "Field1 ${fields[0]}" 
done < file.txt 
+0

不需要傳遞給另一個像'line'這樣的變量。你可以做'而IFS =';'讀-ra領域'。 – konsolebox

+0

@ konsolebox到底!謝謝,修復。 –

2

這可能與你的awk的一個bug。嘗試其他格式,如這些:

while read l 
do 
    n=`echo "${l}" | awk -F\; '{print NF}'` 
    field1=`echo "${l}" | awk -F\; '{print $1}'` 
    field2=`echo "${l}" | awk -F\; '{print $2}'` 
    field3=`echo "${l}" | awk -F\; '{print $3}'` 
    echo "${n} ${field1} ${field2} ${field3}" 
done < temp 

或者

while read l 
do 
    n=`echo "${l}" | awk -v 'FS=;' '{print NF}'` 
    field1=`echo "${l}" | awk -v 'FS=;' '{print $1}'` 
    field2=`echo "${l}" | awk -v 'FS=;' '{print $2}'` 
    field3=`echo "${l}" | awk -v 'FS=;' '{print $3}'` 
    echo "${n} ${field1} ${field2} ${field3}" 
done < temp 

或者

while read l 
do 
    n=`echo "${l}" | awk 'BEGIN{FS=";"}{print NF}'` 
    field1=`echo "${l}" | awk 'BEGIN{FS=";"}{print $1}'` 
    field2=`echo "${l}" | awk 'BEGIN{FS=";"}{print $2}'` 
    field3=`echo "${l}" | awk 'BEGIN{FS=";"}{print $3}'` 
    echo "${n} ${field1} ${field2} ${field3}" 
done < temp 

嘗試像mawknawk其他awks爲好。

+1

這不是他awk的錯誤,這是一個功能。或者也許缺少一個特徵('--field-separator')會更準確。 –

+0

@EdMorton但是,如果該選項不被接受,不會awk顯示錯誤消息?如果功能被識別,但還沒有按照它的方式工作,那麼我認爲這是一個錯誤。 – konsolebox

+1

awk --foo對於一些awks來說是一個有效的awk腳本(我不確定哪些支持長選項 - GNU可以,但還有其他什麼?)。與awk --field-separator類似,它將遞減名爲field的變量,並從中減去名爲separator的變量的值,或者將它作爲2個單獨的語句進行操作。 –