2016-05-20 77 views
1

我有一個非常簡單的awk腳本,需要查看一個字符串並替換雙美元符號($$),雙美元符號與中間數字($ 123 $)和單美元符號($)的任何實例和_。我用gsub在兩個正則表達式中很容易做到這一點,但是我覺得我應該可以用一個正則表達式來完成它,並且它讓我瘋狂到無法鎖定它。可能對時間或速度無關緊要,但在這一點上,我只需要知道我是否正確地採取了更加簡潔的方式,或者我是否瘋了。

這是我目前有:

gsub (/\$[0-9]*\$/, "_", $1); 
gsub (/\$/, "_", $1); 

我想有使用

gsub (/\$[0-9]*\$*/, "_", $1); 

將其設置在同一行沒有問題,但我不知道有一個實例單一的美元符號跟隨數字(123美元),我只想取代美元符號而不是數字。所以我需要匹配1美元符號,然後匹配0或更多的數字,然後匹配1美元符號(如果數字匹配),或者如果沒有數字,則匹配0到1(或更多,實際上並不重要)美元符號。

編輯:對不起,我沒有給出一個更好的例子輸入和所需的輸出。

輸入:

foo$bar$$foofoo$353$foobar$123 
abc$123$xyz$$123abc$def$$hij$456$klm 

輸出:

foo_bar_foofoo_foobar_123 
abc_xyz_123abc_def_hij_klm 

希望這是對我想要的東西更清晰。

+1

'\ $ ' – melpomene

+1

'/^\ $(\ d + \ $)?$ /' –

+0

您的問題包括簡潔,可測試的樣本輸入和期望的輸出。包含可能難以讓腳本正確使用的情況以及在輸入和輸出中匹配要匹配的字符串的上下文(如果您沒有刪除它)尤其重要。 –

回答

2

您的要求不是很清楚,但這是你想要的嗎?

$ awk '{sub(/\$([0-9]*\$)*/,"_")}1' file 
_ - match 
_ - match 
_ - match 
_123 - don't match 

IDK如果上述預期的輸出或沒有給予我應該是你貼的樣品輸入:(?[0-9] + \ $ | \ $)

$ cat file 
$ - match 
$$ - match 
$124$ - match 
$123 - don't match 
1

我不認爲awk在其正則表達式中支持負向預測,因此您需要使用程序邏輯。

gsub(/\$[0-9]*\$/, "_", $1); 
if ($1 ~ /\$/ && $1 !~ /\$[0-9]/) gsub(/\$/, "_", $1); 

但是,這不會像$foo $123字符串工作,因爲$123防止正在做任何換人。

如果您使用GNU Awk,則可以使用其gensub函數在替換中使用捕獲組。然後,您可以匹配$後跟非數字的內容,並將非數字複製到替換中。

gensub(/\$([^0-9]|$)/, "_\\1", "g", $1); 
相關問題