包含FS字符的打印字段?

3

在 AWK 中要处理的记录有以下可能的格式:

foobar 是固定长度的,serialno 是可变长度的,并且我想捕获的字段可能包含零个或多个下划线。

foobar_823932230_processname.txt
foobar_82393280_process_name.txt
foobar_8239330_foo_process_name.txt

期望输出

processname
process_name
foo_process_name

如果我使用FS="[_.]",那么我可以打印出$3,这适用于第一条记录但不适用于第二和第三条。
我该如何捕获序列号和.txt之间的所有内容?
我正在编辑需要更改的旧版AWK代码。一旦正确捕获了这个字段,awk进程就会继续生成额外的输出。

1
使用GNU sed的一行代码:sed -E 's/^([^_]*_){2}//; s/\.[^.]*$//' file - M. Nejat Aydin
5个回答

6
这个 cut + cut 结果应该也是正确的:
cut -d_ -f3- file | cut -d. -f1

processname
process_name
foo_process_name

一个 awk 解决方案是使用这个正则表达式:
awk '{gsub(/^([^_]+_){2}|\..*$/, "")} 1' file

4

如果使用启用了 ERE(如 GNU sed 和 BSD/OSX sed)的 -E 的 sed:

$ sed -E 's/([^_]+_){2}(.*)\.txt$/\2/' file
processname
process_name
foo_process_name

使用任何POSIX sed:

$ sed 's/\([^_]\{1,\}_\)\{2\}\(.*\)\.txt$/\2/' file
processname
process_name
foo_process_name

使用GNU awk:

$ awk '{$0=gensub(/([^_]+_){2}(.*)\.txt$/,"\\2",1)} 1' file
processname
process_name
foo_process_name

使用任何awk:

$ awk '{sub(/([^_]+_){2}/,""); sub(/\.txt$/,"")} 1' file
processname
process_name
foo_process_name

3

请尝试以下操作,这些操作已经编写并测试过,示例已经显示。

awk 'match($0,/.*[0-9]+_/){print substr($0,RSTART+RLENGTH)}'  Input_file

2
使用
$ awk 'BEGIN{FS="[[:digit:]]+_"} {gsub(/\..+$/,"", $2); print $2}' file
processname
process_name
foo_process_name

这个工作是通过将字段分隔符FS设置为一个数字后跟_来完成的,并通过使用gsub去掉生成的变量$2中的文件扩展名。

2

看起来您需要调整一个现有的 awk 脚本以满足此要求。很遗憾 awk 没有附带一个 join 函数,但我们可以自己编写:

function join_fields(from, to, joiner,     result, i, sep) {
  for (i=from; i<=to; i++) {
    result = result sep $i
    sep = joiner
  }
  return result
}

示例:

awk -F '[_.]' '
  function join_fields(from, to, joiner,     result, i, sep) {
    for (i=from; i<=to; i++) {
      result = result sep $i
      sep = joiner
    }
    return result
  }

  {
      field = join_fields(3, NF-1, "_")
      print $0, "\t", field
  }
' <<END
foobar_823932230_processname.txt
foobar_82393280_process_name.txt
foobar_8239330_foo_process_name.txt
END

foobar_823932230_processname.txt     processname
foobar_82393280_process_name.txt     process_name
foobar_8239330_foo_process_name.txt      foo_process_name

++ 非常有用的 join_fields 函数 - anubhava

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接