如何用 shell 变量替换一个字段为另一个字段?

如何用 shell 变量替换一个字段为另一个字段?

考虑以下代码:

renamed_column='2
6
10
8
22
20
6-
18
8-
12
16'

array1='2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389'

我想使用命令替换第一个$1字段。array1renamed_columnawk

我的尝试是基于使用,awk -v v="$renamed_column" '{$1=v; print $0}' <<< "$array1"但这不起作用。

所需的输出为:

2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

答案1

$ awk -v v="$renamed_column" 'BEGIN{split(v,r)} {$1=r[NR]} 1' <<<"$array1"
2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

当然,还有很多其他方法可以做到这一点,上面只是展示了如何通过对原始命令进行最小的更改来做到这一点。

上面将 shell 标量变量的内容保存renamed_column到 awk 标量变量中v,然后将 的内容拆分v为 awk 数组r,然后输入行逐行更改每个第一个字段的值(来自)以附加按索引索引的<<<"$array1"内容r[]当前行号存储在NR.

答案2

array1.txt如果您有两个文件和中的数据renamed_column.txt,您可以执行以下操作:

awk -v replfile=renamed_column.txt '{getline x < replfile; $1 = x; print; }' array1.txt  > output.txt

例如,如果renamed_column.txt是您的输入数据,稍微缩写一下

20
6-
18
8-
12

并且array1.txt是对应的

20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711

那么结果output.txt就是

20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711

如果您有这样的 shell 变量中的数据(并坚持保持这种方式),您可以使用进程替换(在 Bash/ksh/zsh 中)将数据通过管道传输到 awk:

awk -v replfile=<(echo "$renamed_column") '{getline x < replfile; $1 = x; print; }' <(echo "$array1")

但如果您打算使用 awk,处理文件中的数据会更容易。

答案3

根据对此答案的评论,数据以制表符分隔,而不是问题中出现的空格分隔。考虑到这一点,下面的代码已被修改。

使用pastecut代替awk,并假设您使用的 shell 支持此处字符串重定向<<<"..."并使用 进行替换<(...)

paste - <( cut -f 2- <<<"$array1" ) <<<"$renamed_column"

这用于paste创建从实用程序的标准输入读取的两个制表符分隔字段和一个临时文件。

标准输入(由-命令行上的占位符表示paste)是第一个字段,来自 中字符串的输入重定向$renamed_column

临时文件是通过进程替换动态创建的,并提供由 处理的第二个字段paste。进程替换运行cut,它从字符串中提取除第一个制表符分隔字段之外的所有字段$array1,并通过另一个此处字符串读取该字符串。

如果您的数据位于文件中,只需将上面的此处字符串重定向替换为文件名即可:

paste new_column_1 <( cut -f 2- old_data )

相关内容