2

我有一个看起来像这样的大 .csv 文件

19186;1964;F;001;;;;19000101;21000101;20110630
19187;1972;M;001;MMag. Dr.;;;19000101;21000101;20110630
19190;1936;F;999;3;;;19000101;21000101;20110630

每次第 5 个值不是小于 10(不是 0-9)的整数时,都应将其删除。所以结果应该是这样的

19186;1964;F;001;;;;19000101;21000101;20110630
19187;1972;M;001;;;;19000101;21000101;20110630
19190;1936;F;999;3;;;19000101;21000101;20110630

如何做到这一点sed

4

3 回答 3

3

您可以在 sed 中执行此操作,但使用 awk 更简单:

awk 'BEGIN{FS=OFS=";"} $5!~/^[0-9]$/{$5=""} 1' file
于 2012-11-21T17:37:08.463 回答
3

如果您可以改用,我认为awk这比解决方案更容易阅读:sed

#!/bin/bash

awk 'BEGIN{FS=OFS=";"}
     {if (($5 >= 10) || ($5 < 0) || ($5 % 1 != 0)) {$5=""} print}' in_file

输入:

19186;1964;F;001;;;;19000101;21000101;20110630
19187;1972;M;001;MMag. Dr.;;;19000101;21000101;20110630
19190;1936;F;999;3;;;19000101;21000101;20110630
19190;1936;F;999;-3;;;19000101;21000101;20110630
19190;1936;F;999;3.5;;;19000101;21000101;20110630
19190;1936;F;999;10;;;19000101;21000101;20110630

输出:

19186;1964;F;001;;;;19000101;21000101;20110630
19187;1972;M;001;;;;19000101;21000101;20110630
19190;1936;F;999;3;;;19000101;21000101;20110630
19190;1936;F;999;;;;19000101;21000101;20110630
19190;1936;F;999;;;;19000101;21000101;20110630
19190;1936;F;999;;;;19000101;21000101;20110630

解释:

  • awk: 调用 awk 命令
  • '...': 在单引号内提供 awk 的说明
  • BEGIN{FS=OFS=";"}:在读取输入之前,告诉awk;用作输入和输出的分隔符​​(FS 代表字段分隔符,OFS 代表输出字段分隔符)
  • {if (($5 >= 10) || ($5 < 0) || ($5 % 1 != 0)) {$5=""}:如果第 5 个字段不在 之间0-9,或者不是整数,则将该字段设置为空字符串。
  • print:打印(可能)修改的行。
  • in_fileawk:指定“in_file”作为脚本的输入文件
  • (可选)添加> out_file到上述脚本的末尾以将输出重定向到文件而不是stdout

或者:对于更清洁和更强大的解决方案,请参阅 Ed 的回答。

于 2012-11-21T17:26:00.687 回答
2

这可能对您有用(GNU sed):

sed -r 's/^(([^;]*;){4})[^;0-9]+/\1/' file
于 2012-11-21T22:08:31.947 回答