删除文本文件中包含少于4个管道的行

时间:2016-05-08 17:22:38

标签: linux bash awk sed s

我有一个文本文件,数据由4个单独的|分开 文件中有一些问题行。这些行包含少于4个管道。 不需要问题行中的数据,我想在文件上运行一个命令,删除包含少于四个管道的任何行。我还想知道之后删除了多少行,所以如果在应用命令后可以在屏幕上打印这将是理想的。

示例数据:

865|Blue Moon Club|Havana Project|34d|879
899|Soya Plates|Dimsby|78a|699
657|Sherlock
900|Forestry Commission|Eden Project|68d|864

期望的输出:

865|Blue Moon Club|Havana Project|34d|879
899|Soya Plates|Dimsby|78a|699
900|Forestry Commission|Eden Project|68d|864

我尝试了awk '|>=3' file.txt但没有效果。有很多关于awk的信息,其中一些是我发现的,但由于其庞大的音量,很难找到我想要做的事情。

2 个答案:

答案 0 :(得分:7)

消除界限:

grep '|.*|.*|.*|' file > newfile

计算坏线的数量:

grep -cv '|.*|.*|.*|' file

没有进行编辑;您可以使用sed执行此操作,但对新文件执行此类编辑通常更安全,以避免在出错时丢失数据。

第一个grep模式匹配具有四个管道符号的任何行。 (默认情况下,grep使用" Basic"正则表达式,您必须在其中编写交替运算符\|。因此您可以将|用作普通字符。 )

第二次调用计算(-c)不匹配(-v)行的数量。

这是一个简单的sed解决方案:

sed -n -i.bak  '/|.*|.*|.*|/p' file

-n选项会关闭自动打印,因此该命令仅打印与模式匹配的行。 (同样,默认情况下,sed使用基本正则表达式。)。 -i.bak选项可以进行编辑,创建名为file.bak的原始文件的备份。

如果您想选择完全四个管道的行,您可以使用awk

awk -F'|' 'NF==5' file > newfile

将文件分隔符设置为管道符号,然后选择具有五个字段的行,即具有四个管道的行。

计算行数的有用工具是wc

wc -l file

会告诉你文件中有多少行;如果您计算filenewfile中的行数,则差异显然是删除的数量。你也可以在awk中进行计算,但它有点啰嗦:

awk -F'|' 'NF==5{print;next}{del+=1}END{print del >>"/dev/stderr"}' file > newfile

答案 1 :(得分:2)

这样做:

sed -i.bak '/\([^|]*|\)\{4\}/!d' file

或(如Cyrus's comment

sed -i.bak -E '/(\|[^\|]*){4}/!d' file

或者

sed -n '/^[^|]*|[^|]*|[^|]*|[^|]*|$/p' file > newfile

或者

sed -e '/^[^|]*|[^|]*|[^|]*|$/d' \
    -e '/^[^|]*|[^|]*|$/d' \
    -e '/^[^|]*|$/d' \
    -e '/^[^|]*$/d' \
    -i.bak file

但是这不会给你排队数。要将原始文件上的行计数grep -cv '^[^|]*|[^|]*|[^|]*|[^|]*|$' file运行为rici,或者使用wc -l file命令比较前后的行号

<小时/> 的说明:

前两个sed松散地匹配4个管道(不少于但可以更多),第三个匹配4 |(不多或少)。

第四个sed正好匹配3,2,1和0个管道(|)并删除这些行(就地)并准备原始的备份文件(file.bak)。 / p>