我對 AWK 很陌生,所以為這個基本問題道歉。我發現了許多從檔案中洗掉 Windows 結束行字符的參考資料,但沒有一個與正則運算式匹配并隨后洗掉 Windows 結束行字符。
我有一個名為 infile.txt 的檔案,其中包含如下一行:
...
DATAFILE data5v.dat
...
在 shell 腳本中,我想data5v.dat從這個 infile.txt 中捕獲檔案名引數并洗掉任何回車符,\r,如果存在。回車可能并不總是存在。所以我必須匹配一個單詞,然后洗掉 \r 。
我嘗試了以下方法,但它沒有按我的預期作業:
FILENAME=$(awk '/DATAFILE/ { print gsub("\r", "", $2) }' $INFILE)
我可以將匹配我的正則運算式回傳的字串存盤/DATAFILE/在我的 AWK 陳述句中的變數中以便隨后應用gsub嗎?
uj5u.com熱心網友回復:
檔案名可以包含空格,包括\rs、空格和制表符,因此要可靠地執行此操作,您不能洗掉所有\rs ,gsub()也不能依賴任何欄位,例如$2包含整個檔案名的欄位。
如果您的輸入欄位是制表符分隔的,您需要:
awk '/DATAFILE/ { sub(/[^\t] \t/,""); sub(/\r$/,""); print }' file
否則:
awk '/DATAFILE/ { sub(/[^[:space:]] [[:space:]] /,""); sub(/\r$/,""); print }' file
以上假設您的檔案名不以空格開頭并且不包含換行符。
要測驗任何解決方案的穩健性,請嘗試:
printf 'DATAFILE\tfoo \r bar\r\n' | awk '...' | cat -TEv
并確保輸出如下所示:
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^\t] \t/,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
$ printf 'DATAFILE\tfoo \r\tbar\r\n' | awk '/DATAFILE/ { sub(/[^[:space:]] [[:space:]] /,""); sub(/\r$/,""); print }' | cat -TEv
foo ^M^Ibar$
請注意檔案名中間的空格、^M(CR) 和^I(tab),因為它們應該^M在行尾,但不在行尾。
如果您的版本cat不支持-T,或者-E然后執行您通常所做的任何事情來查找非列印字符,例如od -c或vi輸出。
uj5u.com熱心網友回復:
使用GNU awk,請您嘗試以下操作:
FILENAME=$(awk -v RS='\r?\n' '/DATAFILE/ {print $2}' "$INFILE")
echo "$FILENAME"
它將記錄分隔符分配RS給一個由 0 或 1 組成的序列,\r后跟\n.
作為旁注,不建議對用戶的變數名使用大寫字母,因為它可能與系統保留的變數名沖突。
uj5u.com熱心網友回復:
awk 只是將每一行腳本應用于每個輸入行。您可以輕松洗掉回車,然后將一些其他邏輯應用于輸入行。例如,
FILENAME=$(awk '/\r/ { sub(/\r/, "") }
/DATAFILE/ { print $2 }' "$INFILE")
還要注意何時在 shell 變數周圍加上引號。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/450003.html
