awk:将修改后的列添加到文件并保留原始列

awk:将修改后的列添加到文件并保留原始列

我有一个包含两列的文件:

path/path/target1.target2 column2

使用 awk 我想打印:

column1 column2 target1 target2

我尝试了以下操作来进行修改,但随后我丢失了原始列。

$ awk '{gsub("\\..*","", $(gsub(".*/","", $1))); gsub(".*_","", $1); print $0}'
target1 column2

我怎样才能做到这一点?你能解释一下这种行为吗?

答案1

这是一个awk方法:

$ awk '{ 
         split($1,parts,"."); 
         sub(".*/","",parts[1]); 
         print $1, $2, parts[1], parts[2]
       }' file
path/path/target1.target2 column2 target1 target2

至于为什么你的不起作用,因为罗艾玛解释道,这是因为您正在更改 的值,$1因此无法再按预期打印它。

答案2

我会使用sed而不是awk

sed -E 's!([^/]*)\.([^ ]*) (.*)!& \1 \2!'

单行示例的输出:

path/path/target1.target2 column2 target1 target2

至于您自己的awk命令替换字段的原因,gsub(请参阅man awk)的文档写道,

gsub(r,s,t) gsub(r,s)全局替换,r变量中正则表达式的每个匹配t都被替换为字符串s[...]

换句话说,如果您为 提供了值t,例如$1其中gsub(".*/","", $1)被取代随着替换。您需要$1在应用之前复制到单独的变量gsub,否则使用非标准gensub返回修改后的字符串。

答案3

使用任何 awk:

$ awk '{n=split($1,a,"[/.]"); print $0, a[n-1], a[n]}' file
path/path/target1.target2 column2 target1 target2

或者如果您愿意:

$ awk '{x=$1; gsub(/.*\/|\./,OFS,x); print $0 x}' file
path/path/target1.target2 column2 target1 target2

您的原始脚本存在一些基本问题,您不应试图在此处进行解释,您应该获取 Arnold Robbins 所著的《Effective AWK 编程》第五版一书,并阅读相关内容gsub()及其$含义。

答案4

使用(以前称为 Perl_6)

...既然有sed答案,为什么不用 Perl 和/或 Raku 呢?

~$ raku -ne 'my @a = .split(:skip-empty, /  \.  |  ^ .* <[/]> /)>>.words.flat; say @a.raku;'  file

#OR (more simply)

~$ -ne 'my @a = .split(:skip-empty, /  \.  |  ^ .* <[/]> /).words; say @a.raku;'   file

输入示例:

path/path/target1.target2 column2

示例输出:

path/path/target1.target2 column2 target1 target2

简而言之,使用-ne非自动打印命令行标志逐行读取输入,split任何一个一个.或者从行首到最后一行的路径文本/,然后分成空格分隔的words(即列)。这被存储到@a数组中。对于输出,初始行$_按原样打印,后面跟着@a数组的前两个元素。

https://raku.org

相关内容