如何用另一个值替换空格?

如何用另一个值替换空格?

我有一个带有|分隔符的文件,大约有 8k 条记录。

如果第 3 列为空,我想将其替换为第 2 列中的值。我们如何实现这一目标?

输入:

1|100437251|
2|51414204|
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

输出:

1|100437251|100437251
2|51414204|51414204 
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

我尝试过使用sed命令来替换sed -i "s/ /$2/g" input > output.

答案1

:

sed -E 's/^([^|]*\|)([^|]*)\|$/\1\2|\2/' infile

这部分([^|]*\|)捕获第一列以及分隔符(\1是反向引用)。
这部分([^|]*)捕获第二列(\2是反向引用)。
这部分\|$捕获最后一个分隔符,即行结束符,后面没有任何其他分隔符(意味着第三列为空)。

此部分\1\2|\2使用反向引用地址返回第一列和第二列,然后使用分隔符并再次复制第二列。


如果第三列不为空,但也可能包含空格字符,例如制表符/空格 ( [[:space:]]),请改用此列。

sed -E 's/^([^|]*\|)([^|]*)\|[[:space:]]*$/\1\2|\2/' infile

:

awk 'BEGIN{ FS=OFS="|" } $3 ~/^[[:space:]]*$/ { $3=$2 }1' infile

FS 是F产量S分离器,OFS 是输出F产量S分离器;然后我们检查第三列是否为空/制表符/空格,然后更新其内容与第二列相同。然后打印1

答案2

使用awk, 并将第三个字段替换为第二个字段,除非第三个字段包含非空白字符:

$ awk -F '|' 'BEGIN { OFS = FS } $3 !~ /[^[:blank:]]/ { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

sed如果第三个字段为空或仅包含空格,则用于插入第二个字段的编号:

$ sed 's/\([[:digit:]]\{1,\}\)|[[:blank:]]*$/\1|\1/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

注意到第三个字段似乎总是与第二个字段相同,我们也可以选择忽略测试第三个字段的任何内容,而只是将其强制为第二个字段的值。

首先,与awk

$ awk -F '|' 'BEGIN { OFS = FS } { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

甚至

$ awk -F '|' 'BEGIN { OFS = FS } { print NR, $2, $2 }' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

这也重新创建了第一列。

然后用sed

$ sed 's/|[^|]*$//; s/[[:digit:]]\{1,\}$/&|&/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

sed命令首先删除最后一个字段,然后从被删除字段之前的字段重新创建它。

或者,类似的东西

$ cut -d '|' -f 2 file | sed '=; s/.*/&|&/' | sed 'N; y/\n/|/'
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

它使用 提取数据的第二个字段cut,然后使用=insed枚举行并创建字段的重复项,最后使用正确的分隔符将行号附加到数据。

您还可以在 shell 中结合使用cut和来执行此操作(使用进程替换):pastebash

$ paste -d '|' <( cut -d '|' -f 1,2 file ) <( cut -d '|' -f 2 file )
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

答案3

awk

awk -F'|' -v OFS='|' '{if($3=="")$3=$2}1'

一个简单的sed,如果第二列始终是数字:

sed -E "s/([0-9]*)\|$/\1|\1/"

答案4

使用awk, 来查看是否$3为空(或不为空):

awk -F'|' -v OFS='|' '$3 == "" {$3=$2} 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
  • 或者
awk -F'|' -v OFS='|' 'length($3) == 0 {$3=$2} 1' file

相关内容