更新:請記住,正則運算式是我唯一的選擇。
更新 2:實際上,我也可以使用基于 bash 的解決方案。
嘗試用 perl 正則運算式中的逗號替換雙引號之間的管道(可以多于一個)
例子
continuer|"名字"|123|12412|10/21/2020|"3|7"||是|否|否|
預期輸出(3 和 7 用逗號分隔)
continuer|"名字"|123|12412|10/21/2020|"3,7"||是|否|否|
可能有更多的數字,可能不僅僅是兩個d\|d。它可能是"3|7|2"正確的輸出必須是"3,7,2"那個。我試過以下
cat <filename> | perl -pi -e 's/"\d \|[\|\d] /\d ,[\|\d] /g'
但它只是把實際的字串d 等...
我真的很感謝你的幫助。泰
uj5u.com熱心網友回復:
如果它必須是一個正則運算式,這里是一個更簡單的
perl -wpe's/("[^"] ")/ $1 =~ s{\|}{,}gr /eg' file
不是防彈的,但它應該適用于所示的用例。?
解釋。使用/e修飾符,替換側被評估為代碼。在那里,一個正則運算式在$1下面運行,/r所以原來的 ( $1) 是不變的;$N是只讀的,因此我們無法更改$1,因此無法s///在其上運行“正常”。使用此修飾符回傳更改的字串,如果沒有更改,則回傳原始字串。就像命令一樣。
一旦測驗得足夠好,-i如果需要,添加以“就地”更改輸入檔案。
我必須補充一點,我認為沒有理由至少這部分作業不能使用 CSV 決議器完成......
感謝 ikegami 的改進版本
perl -wpe's/"[^"] "/ $& =~ tr{|}{,}r /eg' file
它更簡單,無需捕獲,并且tr速度更快
?使用問題中的字串進行測驗,僅擴展至此
con|"F, N"|12|10/21|"3|7"||是|"2||4|12"|"a|b"|否|""|結束|
uj5u.com熱心網友回復:
我會使用CSV parser,而不是正則運算式:
#!/usr/bin/env perl
use warnings;
use strict;
use Text::CSV_XS;
my $csv = Text::CSV_XS->new({ binary => 1, sep_char => "|"});
while (my $row = $csv->getline(*ARGV)) {
@$row = map { tr/|/,/r } @$row;
$csv->say(*STDOUT, $row);
}
例子:
$ perl demo.pl input.txt
continuer|"First, Name"|123|12412|10/21/2020|3,7||Yes|No|No|
更冗長,但也更健壯,更容易理解。
uj5u.com熱心網友回復:
您說過Update 2: Actually, I can use a bash based solution as well.,雖然這個腳本不是 bash,但您可以從 bash(或任何其他 shell)呼叫它,我認為這是“基于 bash”的真正意思,所以 - 這將在每個 Unix 機器的任何 shell 中使用任何 awk :
$ awk 'BEGIN{FS=OFS="\""} {for (i=2; i<=NF; i =2) gsub(/\|/,",",$i)} 1' file
continuer|"First, Name"|123|12412|10/21/2020|"3,7"||Yes|No|No|
想象一下,您必須除錯或增強上面清晰、簡單的回圈與您在答案中發布的正則運算式咒語:
's/(?:(?<=")|\G(?!^))(\s*[^"|\s] (?:\s [^"|\s] )*)\s*\|\s*(?=[^"]*")/$1,/g'
記住——有些人在遇到問題時會想“我知道,我會使用正則運算式”。現在他們有兩個問題。.
如果您嘗試修改 perl 腳本以添加此功能,我相信您可以在 perl 中本地使用 awk 執行我正在執行的操作。
uj5u.com熱心網友回復:
如果你不能安裝模塊,Text::ParseWords是一個核心模塊你可以試試。它可以拆分字串并處理帶引號的分隔符。
use Text::ParseWords;
my $q = q(continuer|"First, Name"|123|12412|10/21/2020|"3|7"||Yes|No|No|);
print join "|", map { tr/|/,/; $_ } quotewords('\|', 1, $q);
作為單行,它將是:
perl -MText::ParseWords -pe'$_ = join "|", map { tr/|/,/; $_ } quotewords('\|', 1, $_);' yourfile.txt
uj5u.com熱心網友回復:
我會使用 Text::CSV_XS。
perl -MText::CSV_XS=csv -e'
csv
in => \*ARGV,
sep_char => "|",
on_in => sub { tr/|/,/ for @{ $_[1] } };
'
您可以提供檔案名作為引數或通過 STDIN 提供資料。
uj5u.com熱心網友回復:
這正在作業
's/(?:(?<=")|\G(?!^))(\s*[^"|\s] (?:\s [^"|\s] )*)\s*\|\s*(?=[^"]*")/$1,/g'
功勞歸功于我的老板在作業
感謝大家觀看。
我希望你們中的一些人意識到某些專案需要某些方法,并且使已經非常復雜的現有結構復雜化并不總是可行的選擇。我知道會有一個襯里,不要因為你不喜歡那個而討厭。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/504250.html
上一篇:Perl對args的取消參考不能用于比較,但它的副本可以
下一篇:在SAS中使用Perl決議字符
