給定一個帶有 col2 的 TSV 檔案,該檔案包含欄位或記錄分隔符 (FS/RS),分別是制表符或回車符,它們被引號轉義/包圍。
$ printf '%b\n' 'col1\tcol2\tcol3' '1\t"A\tB"\t1234' '2\t"CD\nEF"\t567' | \cat -vet
col1^Icol2^Icol3$
1^I"A^IB"^I1234$
2^I"CD$
EF"^I567$
------ --------- ------
| col1 | col2 | col3 |
------ --------- ------
| 1 | "A B" | 1234 |
| 2 | "CD | 567 |
| | EF" | |
------ --------- ------
sed/awk/perl 甚至(最好)miller/mlr 中是否有辦法將那些討厭的字符轉換為空格,以生成以下結果:
------ --------- ------
| col1 | col2 | col3 |
------ --------- ------
| 1 | "A B" | 1234 |
| 2 | "CD EF" | 567 |
------ --------- ------
我無法讓 miller 6.2 進行正確的轉換(嘗試使用 DSL put/gsub),因為它無法識別選項卡或 CR/LF 是破壞欄位編號的列的一部分:
$ printf '%b\n' 'col1\tcol2\tcol3' '1\t"A\tB"\t1234' '2\t"CD\nEF"\t567' | mlr --opprint --barred --itsv cat
mlr : mlr: CSV header/data length mismatch 3 != 4 at filename (stdin) line 2.
uj5u.com熱心網友回復:
如果你跑
printf '%b\n' 'col1\tcol2\tcol3' '1\t"A\tB"\t1234' '2\t"CD\nEF"\t567' | \
mlr --c2t --fs "\t" clean-whitespace
col1 col2 col3
1 A B 1234
2 CD EF 567
我正在使用mlr 6.2。
uj5u.com熱心網友回復:
perl -MText::CSV_XS=csv -e'
csv
in => *ARGV,
on_in => sub { s/\s / /g for @{$_[1]} },
sep_char => "\t";
'
或者s/[\t\n]/ /g,如果您愿意。
可以全部放在一條線上。
從由引數或 STDIN 命名的檔案接受輸入。
uj5u.com熱心網友回復:
一個好的庫可以很好地處理嵌入引號和換行符之類的事情,并提供靈活性
在帶有Text::CSV的 Perl 腳本中
use warnings;
use strict;
use Text::CSV;
my $file = shift // die "Usage: $0 filename\n";
my $csv = Text::CSV->new( { binary => 1, sep_char => "\t", auto_diag => 1 } );
open my $fh, $file or die "Can't open $file: $!";
while (my $row = $csv->getline($fh)) {
s/\s / /g for @$row; # collapse multiple spaces, tabs, newlines
$csv->say(*STDOUT, $row);
}
請注意建構式的許多其他選項,它們可以幫助處理各種例外情況。
這可以適合單線,其功能界面(帶有csv)特別適合于此。
uj5u.com熱心網友回復:
使用 GNU awk 處理 multi-char RS、RT和gensub():
$ awk -v RS='"([^"]|"")*"' '{ORS=gensub(/[\n\t]/," ","g",RT)} 1' file
col1 col2 col3
1 "A B" 1234
2 "CD EF" 567
以上僅用于RS隔離每個"..."字串并將其保存在 中,然后用空白RT替換該字串中的每個\n或中的內容并將結果保存在 中,然后列印記錄。\tORS
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/486984.html
