簡體   English   中英

如何使用Perl替換運算符禁用變量插值?

[英]How can I disable variable interpolation with the Perl substitution operator?

我正在嘗試替換VMS上的文本文件中的特定行。 通常,這是一個簡單的Perl單線程。 但是當替換方是包含VMS路徑的符號時,我遇到了問題。 這是文件和我嘗試的內容:

file1.txt的內容:

foo
bar
baz
quux

嘗試替換第3行:

$ mysub = "disk$data1:[path.to]file.txt"
$ perl -pe "s/baz/''mysub'/" file1.txt

產生以下輸出:

foo
bar
disk:[path.to]file.txt
quux

看起來Perl過於苛刻,用一個不存在的變量的內容替換路徑的$data1部分(即什么都沒有)。 運行調試器確認了這一點。 我沒有提供/e ,所以我認為Perl應該直接替換文本。 有沒有辦法讓Perl這樣做?

(另請注意,我可以在linux命令行中重現類似的行為。)

正如Ruakh在閱讀我的評論時發現的那樣,perl插值問題可以通過訪問%ENV哈希來解決,而不是使用shell變量:

perl -pwe "s/baz/$ENV{mysub}/" file1.txt

添加-w因為我不相信即使在單行中也不使用warnings

只需正確混合引號和雙引號,您就可以到達:

我們創建了“string”+“替換符號”+“string”的緊密連接。 兩個雙引號字符串包含替換的單引號。 Contrived ......但它確實有效。

$ perl -pe "s'baz'"'mysub'"'" file1.txt

這是一個DCL級別的解決方案。

對於Perl解決方案,使用q()運算符作為非插值字符串並執行它。 使用簡單的DCL替換將符號填入parens。 這是我的最愛,因為它(幾乎)對我有意義,並且不會引起混淆。

$ perl -pe "s/baz/q(''mysub')/e" file1.txt

幾十年來甚至沒有見過VMS系統,但是......逃避你的印記?

$ mysub = "disk\$data1:[path.to]file.txt"

或者可能

$ mysub = "disk\\$data1:[path.to]file.txt"

對於sh或衍生物,我會使用

perl -pe'BEGIN { $r = shift(@ARGV) } s/baz/$r/' "$mysub" file1.txt

否則,你必須以某種方式將mysub的值轉換為Perl字符串文字。 那會更復雜。 找到你的shell的等價物。

由OP編輯:

是的,這很有效。 VMS等價物是

perl -pe "BEGIN { $r = shift(@ARGV) } s/baz/$r/" 'mysub' file1.txt

使用sed。

Sed不會嘗試將$data1插入為變量,因此您應該得到您想要的。

$ sed -e "s/baz/''mysub'/" file1.txt

你必須逃離$\\$ 否則,Perl中看到一個變量引用,並替換字符串$data1與內容$data1正則表達式求值之前。 由於你沒有定義$data1它當然是空的。

您可以使用以下代碼:

$ mysub='disk\$data1:[path.to]file.txt'
$ perl -pe 's/baz/'$mysub'/' FILE
foo
bar
disk$data1:[path.to]file.txt
quux

您可以嘗試使用邏輯名稱而不是DCL符號:

$ define mysub "disk$data1:[path.to]file.txt"
$ $ perl -pe "s/baz/mysub/" file1.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM