gpt4 book ai didi

bash - 用不同文件中的列替换文件中的列,同时保留格式

转载 作者:行者123 更新时间:2023-11-29 09:17:37 25 4
gpt4 key购买 nike

我遇到了一个对高级 shell 用户来说似乎不太难的问题。问题就在这里。

我有 2 个文件:

File1 的格式如下:

ALPH      1  M   GIF M   1      11.111  23.123  -4.412  1.00  0.00           A
ALPH 2 BA GIF M 1 22.222 78.251 -6.215 2.00 0.00 B
ALPH 3 C GIF M 1 22.223 46.321 -6.124 3.00 0.00 C
ALPH 4 D GIF M 1 23.333 15.214 -6.125 4.00 0.00 D
ALPH 5 AB GIF M 1 24.111 61.458 -8.214 5.00 0.00 E
ALPH 6 LM GIF M 1 25.333 78.214 -9.321 6.00 0.00 F
ALPH 7 BA GIF M 1 17.645 87.256 -9.365 7.00 0.00 G
ALPH 8 BA2 GIF M 1 14.125 19.365 -1.258 8.00 0.00 H
-
-

只有一列的 File2:

-0.14
-0.47
-0.58
-0.69
-0.25
-0.69
-0.12
-0.44

我想用 File2 中的唯一一列替换 File1 中的第 11 列。我执行以下操作

paste File1 File2 | awk '{$11=$13;$13=""}1' > output

虽然它很好地替换了列,但它弄乱了我想保留的 File1 的原始格式。正如您所看到的,File1 的所有字段之间有不同数量的空格,即使在替换 $11 之后我也想保留它。

我尝试了几种方法,包括 columnprintf 但似乎都没有用。也许我做错了什么。

有谁知道我怎样才能最好地使用 awk 或 sed 达到预期的结果?

谢谢!

罗希特

最佳答案

当您在 awk 中为字段赋值时,它会使用 OFS 的当前值重新编译当前记录以分隔字段。然后,要保留原始间距,您不能为字段分配新值。相反,您必须使用 RE 来描述在分配前后要跳过多少非空格/空格。像这样使用 GNU awk 将字母“c”(第 3 个字段,因此下面的数字“2”表示要跳过的前导字段数)替换为单词“BOB”:

$ echo "a   b c    d e" |
gawk '{print gensub(/(([^[:space:]]+[[:space:]]+){2})[^[:space:]]+/,"\\1BOB","")}'
a b BOB d e

这会保留间距,因为您正在处理整个记录,而不仅仅是一个字段,因此 awk 不会重新编译记录。

所以对于你的情况是:

$ cat file1
ALPH 1 M GIF M 1 11.111 23.123 -4.412 1.00 0.00 A
ALPH 2 BA GIF M 1 22.222 78.251 -6.215 2.00 0.00 B
ALPH 3 C GIF M 1 22.223 46.321 -6.124 3.00 0.00 C
ALPH 4 D GIF M 1 23.333 15.214 -6.125 4.00 0.00 D
ALPH 5 AB GIF M 1 24.111 61.458 -8.214 5.00 0.00 E
ALPH 6 LM GIF M 1 25.333 78.214 -9.321 6.00 0.00 F
ALPH 7 BA GIF M 1 17.645 87.256 -9.365 7.00 0.00 G
ALPH 8 BA2 GIF M 1 14.125 19.365 -1.258 8.00 0.00 H
$
$ cat file2
-0.14
-0.47
-0.58
-0.69
-0.25
-0.69
-0.12
-0.44
$
$ gawk 'NR==FNR{map[FNR]=$0; next} {print gensub(/(([^[:space:]]+[[:space:]]+){10})[^[:space:]]+/,"\\1" map[FNR],"")}' file2 file1
ALPH 1 M GIF M 1 11.111 23.123 -4.412 1.00 -0.14 A
ALPH 2 BA GIF M 1 22.222 78.251 -6.215 2.00 -0.47 B
ALPH 3 C GIF M 1 22.223 46.321 -6.124 3.00 -0.58 C
ALPH 4 D GIF M 1 23.333 15.214 -6.125 4.00 -0.69 D
ALPH 5 AB GIF M 1 24.111 61.458 -8.214 5.00 -0.25 E
ALPH 6 LM GIF M 1 25.333 78.214 -9.321 6.00 -0.69 F
ALPH 7 BA GIF M 1 17.645 87.256 -9.365 7.00 -0.12 G
ALPH 8 BA2 GIF M 1 14.125 19.365 -1.258 8.00 -0.44 H

如果你没有 gawk(对于 gensub()),你可以使用 match() 来查找你关心的字段的开始位置,第二个 match() 用于它的结束位置,以及明智的 substr()s 到将其替换为新值。

@GlennJackman 在他的解决方案中提到了固定宽度的字段。如果那是你所拥有的,你可以使用 GNU awks FIELDWIDTHS 变量来指定每个字段的宽度并使用它。有关详细信息,请参阅 gawk 手册。

关于bash - 用不同文件中的列替换文件中的列,同时保留格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20552378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com