描述字段值可能存在于多行中。我想将其放入单行中,如下所示。该文件将具有固定数量的列。
输入文件:
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple, Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana,
Orange, Grapes
Kiwi||||
任何不包含“|”的行或包含“|”的行但“|”的计数该行中的值等于 4,则该行应附加到包含“|”的上一行
输出文件:
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple,Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana,Orange, Grapes Kiwi||||
答案1
这是一个简单的 Python 脚本,可以完成您想要的操作:
#!/usr/bin/env python2
# -*- ascii -*-
"""rewrapcsv.py"""
import sys
datafile = sys.argv[1]
columns = int(sys.argv[2])
with open(datafile) as filehandle:
buffer = []
for line in filehandle:
buffer.extend(line.strip().split('|'))
while len(buffer) >= columns:
print('|'.join(buffer[0:columns]))
buffer = buffer[columns:]
print('|'.join(buffer[0:columns]))
data.csv
这是取自您的问题的示例数据文件 ( ):
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple, Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana,
Orange, Grapes Kiwi||||
以下是运行脚本的方法:
python rewrapcsv.py data.csv 6
这是输出:
Number|Level|Description|Unit|Rate|Special Rate
Notes|101|0|Apple, Orange, Banana||6.80%
8.56|Free||1|Fruits:|
|||102|2|Banana,
Orange, Grapes Kiwi||||
答案2
Awk
解决方案:
awk -F'|' 'r{ if (NF!=1 && NF!=5) print r; else { print r,$0; next } }{ r=$0 }' file
-F'|'
- 字段分隔符r
- 包含以前的记录
输出:
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple, Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana, Orange, Grapes Kiwi||||
答案3
sed
解决方案:
sed -E -e :a -e '/(\|.*){6,}/!N;s/\n/ /;ta' file
扩展正则表达式(\|.*){6,}
匹配至少包含 6 个小节的行。如果当前行与该行不匹配,则附加下一行 ( !N
)。
s/\n/ /
用空格替换换行符。如果进行了替换,则意味着附加了一行,因此我们需要再次测试,因此ta
跳转到标记:a
是否进行了替换。完毕。
答案4
使用前...
ex +'g/^\([^|]\+\(|[^|]*\)\{4}\|[^|]\+\)$/norm! kgJ' +wq file
或者,同样的事情,但使用“非常神奇”模式(\v
模式的开头)......在我看来,眼睛更容易一些,因为只|
需要转义字面意思......
ex +'g/\v^([^\|]+(\|[^\|]*){4}|[^\|]+)$/norm! kgJ' +wq file
Vim 在现代系统中实现了 Ex,因此如果您了解 Vim,这些ex
命令可能看起来很熟悉。第一个命令(第一个之后+
)是“全局”命令。如果找到其中一种模式(没有找到或一行中有|
四个),则执行正常模式命令,用于向上移动一行 ( ) 并加入下一行 ( )。|
k
gJ
这是为数不多的便携式解决方案之一将就地更新文件。 (sed -i
例如,GNU使用临时文件)。
这是您的输入以及第二个模式的测试(“行不包含 |”):
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple, Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana,
Orange, Grapes Kiwi||||
103|2|Watermelon,
Pear, Raspberry, Lime
结果:
Number|Level|Description|Unit|Rate|Special Rate|Notes
101|0|Apple, Orange, Banana||6.80%|8.56|Free
|1|Fruits:||||
102|2|Banana,Orange, Grapes Kiwi||||
103|2|Watermelon,Pear, Raspberry, Lime