过滤掉csv文件第11列7个字符的正则表达式

Regex that filters out 7characters in 11th column of csv file

所以我有这个 csv 文件 casper.csv。它有一行中断了这个在离岸运行的数据库进程。所以我只是 将此添加到处理文件的脚本中,它是 sed 它在脚本中。中提琴 - 没有 phone 个电话。

cd /come/and/play/with/us
    sed -i '/D,642,0642,WOW,MOM,,M,,S,S,DANNNYY,213,213,/d' /come/and/play/with/us/casper.csv

无论如何 - 我在凌晨 3 点开始接到电话,说离岸数据库进程又要死了。我的 sed hack 无法捕捉到不同的错误行。 后来我们发现,如果第 11 列超过 6 个字符,它会打破 数据库进程。

离岸小哥用这个找坏线:

/come/and/play/with/us/casper.csv | perl -nle 'print if /,,,,(.{7}),/'
D,,,WOW,,,M,,,,DANNNYY,-213.00,-213,69036R400
D,,,WOW,,,M,,,,QSP-U=C,-4.00,-4,76090H103

所以现在我用离岸人的perl one liner找出会破坏离岸数据库进程的那一行,然后用vi在文件中手动删除它。但是我不明白 perl one liner 是如何工作的。 因为它在 {7} 之前只有 4 个逗号,而原样应该有 10 个。并且在 7?

之前没有 \w 或 \d
 perl  -nle 'print if /,,,,(.{7}),/'

我要构建的大多数正则表达式看起来像这样

,\w,\w+,\w+,\w+,\w+,\w+,\w+,\w+,\w+,\w{7},\w+,\w+,

但即使这样也不是一直有效,因为有时逗号之间没有任何内容 - 即 'D,,,WOW'

问题是大老板发现我手动做这件事并希望它自动化。 我需要在上游 bash 脚本中添加一些内容,该脚本将踢出 csv 文件中第 11 列包含超过 6 个字符的任何行 - 这六个字符可以是任何字符,有时它们什么都不是(没有 space) 逗号之间...即 'D,,,WOW'

只要数据本身从来没有任何逗号,就可以使用

 perl -ne 'print if length((split /,/)[10]) > 6' /come/and/play/with/us/casper.csv

当然这会打印出错误的行。您可以将 if 替换为 unless 以打印有效行。


更新

或者,完全使用 Perl 的命令行选项

perl -F, -e'print if length $F[10] > 6' /come/and/play/with/us/casper.csv

哦,哇哦。如果我见过的话,那就是一个肮脏的黑客。 ,,,,(.{7}), 正则表达式不匹配第 11 列,它匹配四个逗号后跟七个任意字符后跟一个逗号的任何内容。这意味着一行

D,,,WOW,,,M,,,,DANNNYYY,-213.00,-213,69036R400
           ^^^^1234567^ <-- last one not a comma

(with 8 characters in the column 11)不会被抓到,一行

D,,,,WOWWOWW,,M,,,,DANNNY,-213.00,-213,69036R400
 ^^^^1234567^ <-- match

用四个逗号后跟7个字符后跟在不同地方的逗号。确实,由于这 7 个字符中没有任何内容阻止它匹配其他逗号,

D,,,,WOW,,M,,,,DANNNYYY,-213.00,-213,69036R400
 ^^^^1234567^ <-- match

也算坏了

如果是我,我会用 awk 过滤掉虚线。

awk -F, 'length() < 7' /come/and/play/with/us/casper.csv

将打印 casper.csv 中第 11 个字段长度小于 7 个字符的所有行。如果你有最新的 GNU awk(4.1.0 或更高版本),你可以使用

awk -i inplace -F, 'length() < 7' /come/and/play/with/us/casper.csv

就地更改文件,尽管我个人希望保留原件以防万一。

这可能适合您 (GNU sed):

sed '/^\([^,]*,\){\}[^,]\{7\}/d' file

假设 , 是唯一的分隔符,这将删除纯 CSV 文件第 11 个字段中包含 7 个或更多字符的行。它查找十个包含零个或多个非逗号字符后跟一个逗号的字段,从行的开头开始,最后尝试匹配第 11 个字段中的七个非逗号字符。