我有一个文件:
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