![替换字段中的分隔符](https://linux22.com/image/155498/%E6%9B%BF%E6%8D%A2%E5%AD%97%E6%AE%B5%E4%B8%AD%E7%9A%84%E5%88%86%E9%9A%94%E7%AC%A6.png)
我有一个 csv,其中字段由 分隔|
。
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a|b | path: some
分隔符|
有时会出现在第四个字段(字段Condition
)中。我想将其替换|
为OR
:
Condition: a|b
会变成: Condition: a OR b
我如何使用 sed 或 awk 来实现此目的?
答案1
awk -F'|' -v OFS='|' 'NF == 6 {$4 = $4 " OR " $5; $5=$6; NF--} 1' file
这仅适用于管道分隔字段的数量。您预计有 5 个,但如果有 1 个多余的,请与所需的字符串连接。
或者,GNU sed:
sed 's/|/|/5; ta; n; :a; s/|/ OR /4' file
如果有5根管子,则更换第4根。不适用于 MacOS 上的默认 sed - 如果分号被换行符替换,MacOS sed 可以使用这些命令(对于 BSD 派生的 sed,标签名称似乎必须后跟换行符)。
如果有怎么办更多的多于 1 个额外管道?考虑这个文件:
|time: 10:19 | Error: File not found| Condition: None | path: some
|time: 10:20 | Error: File not found| Condition: a|b | path: someh
|time: 12:34 | NO ERROR | Condition: a|b AND c|d AND e|f | path: nil
扩展 sed 解决方案很简单:添加“jump-if”
sed ':b; s/|/|/5; ta; n; :a; s/|/ OR /4; tb' file
awk 变得有点冗长:
awk -F'|' -v O FS='|' '{
while (NF > 5) {
$4 = $4 " OR " $5
for (i = 5; i < NF; i++)
$i = $(i+1)
NF--
}
print
}' file
答案2
对此进行测试:
sed 's/Condition:[ ]*\([a-zA-Z]*\)|\([a-zA-Z]*\)/Condition: \1 OR \2/g' your_file
假设a
和b
是字母。
答案3
Python3 脚本。将 csv 文件分解为由分隔符“|”定义的列表然后如果有多余的字段并且以“条件:”一词开头,则加入这些字段
import csv
for line in list(csv.reader(open('filename', 'r'), delimiter='|')):
if len(line) > 5 and line[3].lstrip().startswith('Condition:'):
print('|'.join(line[:3] + [line[3] + ' OR ' + line[4]]+line[5:]))
else:
print('|'.join(line))
答案4
从您的代码示例来看,定义规则似乎是无论在|
哪里不是两边都有一个空间,那么你想要成为OR
,所以简单
sed -E 's/([^ ])\|([^ ])/\1 OR \2/g' test