如何仅在第二列($2)中使用sed替换字符串
如何用sed仅替换第二列的特定字符?
我懂你这个困扰——想用sed只修改第二列的.为-9,结果全局替换把第一列里的点也给改掉了,太闹心了😅。先把你的场景再理一遍:
输入示例
A.a 1 A.b . A.c 1 A.d 1
期望输出
A.a 1 A.b -9 A.c 1 A.d 1
错误尝试的问题
直接用sed 's/\./-9/g' input > output会全局替换所有.,得到完全不符合预期的结果:
A-9a 1 A-9b -9 A-9c 1 A-9d 1
下面给你两种解决方案,一种是纯sed的精准匹配,另一种是更适合列处理的awk方案:
方案1:用sed精准定位第二列
我们可以利用sed的正则分组捕获,只瞄准第二列的.。假设你的列是用多个空格/制表符分隔的,用这个命令就可以:
sed -E 's/^([^[:space:]]+[[:space:]]+)\./\1-9/' input > output
拆解下这个命令的逻辑:
-E:开启扩展正则,让分组写法更简洁^([^[:space:]]+[[:space:]]+):捕获第一列和后面的分隔符——[^[:space:]]+匹配第一列的所有非空白字符(比如A.a),[[:space:]]+匹配列之间的所有空白,这部分会被存在分组\1里\.:专门匹配第二列开头的那个.(就是你要替换的目标)\1-9:把捕获的第一列+分隔符原封不动保留,然后把.替换成-9
如果你的第二列里可能有多个.需要替换,也可以用sed的嵌套写法,但相对麻烦一些:
sed -E 's/^([^[:space:]]+[[:space:]]+)(.*)/\1'"$(echo '\2' | sed 's/\./-9/g')"/' input > output
方案2:用awk更直观处理列
说实话,sed擅长处理行级的文本替换,但处理列的话,awk天生更顺手,逻辑也更清晰。如果只是替换第二列中等于.的内容,用这个:
awk '{if ($2 == ".") $2 = "-9"; print}' input > output
要是第二列里有多个.需要全部替换,就用gsub全局替换:
awk '{gsub(/\./, "-9", $2); print}' input > output
这样直接指定操作$2列,完全不用担心影响其他列的内容,省心多了~
内容的提问来源于stack exchange,提问作者user9467855
相关产品推荐
相关产品推荐

