我有一个包含两列的文件:
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
数组的前两个元素。