我想洗掉雙引號之間的 CSV 檔案中的所有非法換行符 LF。
"name", "created"
"David A","2022-04-04"
"Mark
B", "2022-04-09"
"Peter C", "2022-05-01"
該檔案被稱為name.csv例如
現在我可以做到
cat name.csv |
| perl -p -e 's/\n/!LF_SYMBOL!/g' \
| perl -p -e 's/"!LF_SYMBOL!"/"!EOL!"/g' \
| perl -p -e 's/!LF_SYMBOL!//g' \
| perl -p -e 's/!EOL!/\n/g' \
> name_new.csv
但它很丑。我想洗掉所有不跟隨雙引號的換行符
我試過了
perl -p -e 's/[^"]\n//' name.csv
和
perl -p -e 's/^[^"]\n//' name.csv
兩者都"\n出于某種原因全部洗掉。
有任何想法嗎?
uj5u.com熱心網友回復:
通常最好使用現有的決議器而不是撰寫自己的決議器。這也不例外。
Text::CSV_XS在處理雙引號欄位中的換行時沒有問題。[1]
如果提供的話,它甚至可以容忍逗號后的空格allow_whitespace => 1。
所以我會使用這個模塊而不是撰寫我自己的決議器。
你只需要這樣:
perl -MText::CSV_XS=csv -e'
csv
in => *ARGV,
allow_whitespace => 1,
on_in => sub { s/\n//g for @{ $_[1] }; };
' name.csv >name_new.csv
輸出:
name,created
"David A",2022-04-04
MarkB,2022-04-09
"Peter C",2022-05-01
如果出于某種原因您想避免 XS,則較慢的 Text::CSV 是一個替代品。
- 處理欄位中的換行需要傳遞
binary => 1,這是使用該csv函式時的默認值。
uj5u.com熱心網友回復:
如果這是一個有效的 CSV 檔案,請使用庫讀取它,例如Text::CSV。他們對嵌入在欄位中的換行沒有問題,然后洗掉這些很簡單
use warnings;
use strict;
use feature 'say';
use Text::CSV;
my $file = shift or die "Usage: $0 file.csv\n";
my $csv = Text::CSV->new(
{ binary => 1, auto_diag => 1, allow_whitespace => 1 });
open my $fh, '<', $file or die "Can't open $file: $!";
while (my $row = $csv->getline($fh)) {
s/\n //g for @$row;
$csv->say(\*STDOUT, $row);
}
如果有一些好處,這也可以在單行中完成。
就目前而言,發布的文本不是有效的 CSV,并且不能由庫直接決議,因為欄位之間缺少逗號。我認為這些是拼寫錯誤,因為問題在多個地方都說“CSV”。請澄清。
屬性接受嵌入的換行符,binary而逗號后的額外空格(嚴格無效)接受allow_whitespace.
uj5u.com熱心網友回復:
由于您有一個類似“CSV”的兩列檔案,并且您想要的只是洗掉兩個欄位內的換行符,因此您可以使用類似的解決方案
perl -0777 -i -pe 's/^("[^"]*(?:""[^"]*)*")\s*,\s*(?1)$/$&=~s!\R !!gr/gme' file.csv
請參閱主要的正則運算式演示。找到匹配項后,第二個正則運算式s!\R !!gr會洗掉匹配項中的所有換行符。
詳情:
^- 一行的開始(由于m標志)("[^"]*(?:""[^"]*)*")- 第 1 組:",零個或多個除 之外的字符",然后是零個或多個重復,""然后是零個或多個除 之外的字符",然后是 a"(匹配其中文字雙引號用 轉義的 CSV 欄位")\s*,\s*- 用零個或多個空格括起來的逗號(?1)- 重復第 1 組模式的子程式$- 行尾(由于m標志)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/470776.html
