如果在另一列中满足条件,则使用 sed 替换 csv 列中的值
Use sed to replace values in a csv column if a condition is met in another column
我有一个 CSV 文件,由几个用逗号分隔的字段组成。
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
当“运动”栏是射击或柔道时,我必须将“名称”栏上的值从小写更改为大写。我只能用sed
。我正在使用这个命令
sed 's/\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\)/,\U\E,,,,,,\shooting|judo,,,,/' athletesv2.csv
但它不起作用,因为它只是在所有行中显示“射击|柔道”。
如何进行这些替换?
注意输出必须是.sed文件,必须使用sed -f script.sed athletes.csv
调用
在输出中我需要保留 header.
我正在使用 Ubuntu Linux.
如果你可以使用 GNU sed
,你可以使用
rx='^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$'
repl=',\U\E,'
sed -E "s/$rx/$repl/" athletes.csv
参见 online demo:
#!/bin/bash
rx='^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$'
repl=',\U\E,'
s='id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
132041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,'
sed -E "s/$rx/$repl/" <<< "$s"
输出:
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
132041664,A JESUS GARCIA,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,
备注:
^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$
是匹配整个字符串的模式(^
是字符串的开头,$
匹配字符串的结尾),它将字段 1 和字段 2 捕获到单独的组中并将字符串的其余部分放入第 3 组。字段 8 模式为 hard-coded、(shooting|judo)
匹配 shooting
或 judo
.
替换中的 \U\E
会将第 2 组值放回大写。
请注意您 cannot use more than
backreference 在 sed 中,因此您需要减少它们的数量并将那些未使用的组分组。
使用sed
$ sed '/^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,shooting\|judo,/s/,[^,]*/\U&/' input_file
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A JESUS GARCIA,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,
这可能适合您 (GNU sed):
sed -E 'h;x;s/[^,]*/\n&\n/8;/\n(shooting|judo)\n/{x;s/[^,]*/\U&/2;x};x' file
复制当前行。
用换行符包围第八个字段的副本,如果该字段包含 shooting
或 judo
,则将第二个字段大写为纯版本。
我有一个 CSV 文件,由几个用逗号分隔的字段组成。
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
当“运动”栏是射击或柔道时,我必须将“名称”栏上的值从小写更改为大写。我只能用sed
。我正在使用这个命令
sed 's/\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\),\(.*\)/,\U\E,,,,,,\shooting|judo,,,,/' athletesv2.csv
但它不起作用,因为它只是在所有行中显示“射击|柔道”。
如何进行这些替换?
注意输出必须是.sed文件,必须使用sed -f script.sed athletes.csv
在输出中我需要保留 header.
我正在使用 Ubuntu Linux.
如果你可以使用 GNU sed
,你可以使用
rx='^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$'
repl=',\U\E,'
sed -E "s/$rx/$repl/" athletes.csv
参见 online demo:
#!/bin/bash
rx='^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$'
repl=',\U\E,'
s='id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
132041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,'
sed -E "s/$rx/$repl/" <<< "$s"
输出:
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A Jesus Garcia,ESP,male,1969-10-17,1.72,64,athletics,0,0,0,
132041664,A JESUS GARCIA,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,
备注:
^([^,]*),([^,]*),([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(shooting|judo),[^,]*,[^,]*,[^,]*,[^,]*)$
是匹配整个字符串的模式(^
是字符串的开头,$
匹配字符串的结尾),它将字段 1 和字段 2 捕获到单独的组中并将字符串的其余部分放入第 3 组。字段 8 模式为 hard-coded、(shooting|judo)
匹配shooting
或judo
.
替换中的 \U\E
会将第 2 组值放回大写。
请注意您 cannot use more than backreference 在 sed 中,因此您需要减少它们的数量并将那些未使用的组分组。
使用sed
$ sed '/^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,shooting\|judo,/s/,[^,]*/\U&/' input_file
id,name,nationality,sex,date_of_birth,height,weight,sport,gold,silver,bronze,info
736041664,A JESUS GARCIA,ESP,male,1969-10-17,1.72,64,shooting,0,0,0,
这可能适合您 (GNU sed):
sed -E 'h;x;s/[^,]*/\n&\n/8;/\n(shooting|judo)\n/{x;s/[^,]*/\U&/2;x};x' file
复制当前行。
用换行符包围第八个字段的副本,如果该字段包含 shooting
或 judo
,则将第二个字段大写为纯版本。