linux - 如何使用sed或awk处理指定列的内容?

标签 linux awk sed

我有这样的文本数据。

2017-08-07 733 AA1(10.7.21.51) AllUsers 631 K:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631(Peter) 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208(Lucy) 2:C
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 K:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 99999(Kate) 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631(Peter) 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631(Peter) 2:C
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999(Kate) T:U 
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999(Kate) 3:U 

本文一共有6列,每列数据用空格分隔。

我想处理第 5 列数据。

一些数据包含第 5 列中的名称。在包含名称的数据之外还有更多的括号。没有名称的列中只有数字。这个号码是员工号。我只想取出第 5 列中的数字,而不是名称。我想要这个效果。

2017-08-07 733 AA1(10.7.21.51) AllUsers 631 K:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 2:C
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 K:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 99999 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 T:U 
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 3:U 

我用这个命令来处理数据。

cat mytextfile|sed 's/(/ /g' > resultfile

但是第3列也被修改了,因为第3列也包含了括号。事实上,我只想处理第 5 列。

我应该用 sed 或 awk 做什么?

最佳答案

使用 sed(简单)

要删除所有只包含字母的括号,请尝试:

$ sed 's/([[:alpha:]]*)//' myfile
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 K:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N 
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 2:C
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 K:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 99999 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 T:U 
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 3:U 

([[:alpha:]]*) 匹配 ( 后跟零个或多个字母字符后跟 )s/([[:alpha:]]*)// 找到这些字符并将它们替换为空字符串。

使用 sed(改进)

这会从第五个字段中删除括号中的字母字符表达式,并且仅从第五个字段中删除:

$ sed -E 's/(([^[:space:]]+[[:space:]]+){4}[^[:space:]]*)\([[:alpha:]]*\)/\1/' myfile
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 K:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 2:C
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 K:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 99999 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 T:U
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 3:U

使用 awk

要删除第五个字段中的任何带括号的表达式:

$ awk -F'[[:space:]]+' '{gsub(/\(.*\)/, "", $5)} 1' myfile
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 K:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 631 1:N
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 2:C
2017-08-07 733 AA1(10.7.21.51) AllUsers 2208 K:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 99999 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 189 AA2(10.7.4.54) AllUsers 631 2:C
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 T:U
2017-08-07 733 AA3(10.7.21.51) AllUsers 99999 3:U

工作原理:

  1. -F'[[:space:]]+'

    这告诉 awk 使用任何 unicode 可识别的空白序列作为字段分隔符。 (默认仅将空格、制表符和换行符序列识别为字段分隔符。)

  2. gsub(/\(.*\)/, "", $5)

    这会在第五个字段 $5 中查找任何带括号的表达式 \(.*\),并将其替换为空字符串 "".

  3. 1

    这是告诉 awk 打印该行的速记。

关于linux - 如何使用sed或awk处理指定列的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57282774/

相关文章:

linux - Centos auxd 进程挂起

python - 拆分配置文件中的文本

vim - 使用 sed 或 awk 枚举替换

linux - gnuplot - 两个图的交集

python - 无法通过python连接到rdp

regex - AWK - 搜索模式 - 将其添加为变量 - 搜索不是变量的下一行并打印它 + 变量

awk - 使用 grep 或 awk 查找 txt 和 csv 文件之间的匹配行

regex - 替换除行尾以外的值

sed - 无法在 aks 中启动 apache-nifi

java - .sh 文件未按 java 预期工作