我有一个文本文件,数据由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
的信息,其中一些是我发现的,但由于其庞大的音量,很难找到我想要做的事情。
答案 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
会告诉你文件中有多少行;如果您计算file
和newfile
中的行数,则差异显然是删除的数量。你也可以在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>