如果有额外分隔符则删除最后一个分隔符

如果有额外分隔符则删除最后一个分隔符

我有一个文件:

a|b|c|d
x|y|z|n|||||||||
p|q|r|s|
g|h|i|
w|e|r||

现在第二行有一个额外的分隔符,我想删除它。我怎么能在unix中做到这一点?

输出应该只有 4 个管道分隔符:

a|b|c|d
x|y|z|n
p|q|r|s
g|h|i|
w|e|r|

答案1

我发现 awk 在这种情况下很容易阅读:

$ awk -F'|' -vOFS='|' '{NF=4}1' file
a|b|c|d
x|y|z|n
p|q|r|s
g|h|i|
w|e|r|

请注意,此答案不会删除尾随管道符号,它只是将输出中的列设置为 4。对于以下修改后的示例:

$ cat file
a|b
x|y|z|n||||
p|q|r|s
g|h|i|
w|e|r||

$ awk -F'|' -vOFS='|' '{NF=4}1' file
a|b||
x|y|z|n
p|q|r|s
g|h|i|
w|e|r|

答案2

grep你可以用一行代码来做到这一点:

cat data.csv | grep -Po '^(\w*\|){3}\w*$'

您也可以使用 Python 轻松完成此操作。这是一个可以执行您想要的操作的 Python 脚本:

#!/usr/bin/env python2
# -*- coding: ascii -*-
"""shortencsv.py"""

import sys

cols = 4

with open(sys.argv[1]) as csvfile:
    for line in csvfile:
        print('|'.join(line.strip().split('|')[:cols]))

你可以像这样运行它:

python shortencsv.py data.csv

答案3

sed单个管道替换每条记录末尾的一个或多个管道。

sed 's/|\+$/|/' infile

样本:

a|b|c|d
x|y|z|n|||
p|q|r|s
g|h|i|sx|sxa
w|e|r||

输出:

a|b|c|d
x|y|z|n|
p|q|r|s
g|h|i|sx|sxa
w|e|r|

答案4

awk 适合更复杂的任务,但是使用 cut 可以更快地完成这个简单的任务:

$ echo "$a"
a|b|c|d
x|y|z|n|||||||||
p|q|r|s|
g|h|i|
w|e|r||

$ time awk -F'|' -vOFS='|' '{NF=4}1' <(for i in {1..100000};do echo "$a";done)

a|b|c|d
x|y|z|n
p|q|r|s
g|h|i|
w|e|r|

real    0m3.850s
user    0m2.105s
sys 0m1.481s

$ time cut -d'|' -f1-4 <(for i in {1..100000};do echo "$a";done)
a|b|c|d
x|y|z|n
p|q|r|s
g|h|i|
w|e|r|
.....
.....

real    0m2.844s
user    0m1.384s
sys 0m1.268s

在你的情况下,只需使用

cut -d'|' -f1-4 inputfile

相关内容