首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >第一列中有空格的awk输出

第一列中有空格的awk输出
EN

Stack Overflow用户
提问于 2020-10-22 00:01:06
回答 3查看 560关注 0票数 1

我试着用awk分割列来打印一个句子,但是第一个列有空格。

我的初学者代码示例:

代码语言:javascript
复制
$ awk '/Linux/ { print "The filename","\""$1"\"","is located in",$2 }' test.txt
The filename "The" is located in test
The filename "Some" is located in file
The filename "File" is located in name
The filename "Something_here" is located in /ABC
The filename "Another_test" is located in /DEFG
The filename "Label" is located in test

From : test.txt

代码语言:javascript
复制
Filename                               Folder         Type
-------------------------------------- -------------- ------
The test file                          /test/folder   Linux
Some file                              /              Linux
File name                              /Temp          Linux
Something_here                         /ABC           Linux
Another_test                           /DEFG          Linux
Label test                             /HIJK          Linux 

我想要达到的目标:(含引号)

代码语言:javascript
复制
The filename "Default file" is located in / 
The filename "The test file" is located in /test/folder

问题是当我使用'space‘或'/’作为分隔符时,在打印时不能得到整行

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-10-23 08:09:51

如果您有GNU AWK,这应该可以做到:

代码语言:javascript
复制
awk 'match($0, /([^\/]+)([^ ]+) *Linux/, arr) { sub(/ +$/, "", arr[1]); printf("The filename \"%s\" is located in %s\n", arr[1], arr[2]) }' test.txt

解释:

代码语言:javascript
复制
# match and store groups in 'arr'
#  - arr[1]: everything up until the first slash (including a lot of whitespace)
#  - arr[2]: first slash until space
#  - rest: also ensure there's 'Linux' after that
match($0, /([^\/]+)([^ ]+) *Linux/, arr) {

  # trim whitespace from the right hand side of the filename
  sub(/ +$/, "", arr[1]);

  # print
  printf("The filename \"%s\" is located in %s\n", arr[1], arr[2])
}

请注意,在其他版本的AWK中,也有一个功能较弱的match版本,使用这些版本也可以实现相同的功能,但是您必须编写更多的代码。

票数 0
EN

Stack Overflow用户

发布于 2020-10-22 10:38:45

我建议使用基于正则表达式和反向引用的替换,加上一个sed命令,以消除源文件的头行:

代码语言:javascript
复制
$ cat test.txt | grep -E 'Linux[ ]*$' | sed -E 's%(.+)([^ ])([ ]+)(/.+)[ ]+Linux[ ]*$%The filename "\1\2" is located in \4%'
The filename "The test file" is located in /test/folder  
The filename "Some file" is located in /             
The filename "File name" is located in /Temp         
The filename "Something_here" is located in /ABC          
The filename "Another_test" is located in /DEFG         
The filename "Label test" is located in /HIJK

正则表达式(regex)的一个很好的引用在Linux手册中。

评论中所要求的详细说明:

  • grep-E选项接受扩展正则表达式(上面的参考文档)。在这里,它用于过滤包含"Linux“字的行,并在每一行末尾加上一些空格(如果有的话)。
  • grep的输出进入sed的输入。
  • sed被传递-E选项(如grep )以接受扩展正则表达式。命令替换了与regex匹配的字符(% chars = "(.+ )( ^ )( +)(/.+) +Linux *$“之间的第一部分)(在% chars =”文件名“\1\2中的第二部分位于\4中)。
  • 第二部分使用反向引用:'\‘后面跟着一个非零十进制数字n,由正则表达式的nth括号子表达式代替。在这里,\1被与这里的文件名第1 "(.+)“匹配的字符串替换,\2被以下的"(^ )”所替代,该字符串是文件名的最后一个字符(从名称中消除以下空格的技巧).

这并不是一个严格的解释,但至少它提供了一些进一步的投入。

另一种解决方案是在sed命令行上传递多个操作。因此,您可以添加一个查询来删除前两个头行,以便使用catgrep来抑制管道。此处“1,2d”意为“删除第1和第2行”:

代码语言:javascript
复制
$ sed -E '1,2d;s%(.+)([^ ])([ ]+)(/.+)[ ]+Linux[ ]*$%The filename "\1\2" is located in \4%' test.txt
The filename "The  test file" is located in /test/folder  
The filename "Some file" is located in /             
The filename "File name" is located in /Temp         
The filename "Something_here" is located in /ABC          
The filename "Another_test" is located in /DEFG         
The filename "Label test" is located in /HIJK

注意:根据手册-E选项切换到使用扩展正则表达式。多年来,GNU sed一直支持它,现在已包含在POSIX中。在旧系统上,如果不支持-r,则可以使用-E

代码语言:javascript
复制
$ sed -r '1,2d;s%(.+)([^ ])([ ]+)(/.+)[ ]+Linux[ ]*$%The filename "\1\2" is located in \4%' test.txt
The filename "The  test file" is located in /test/folder  
The filename "Some file" is located in /             
The filename "File name" is located in /Temp         
The filename "Something_here" is located in /ABC          
The filename "Another_test" is located in /DEFG         
The filename "Label test" is located in /HIJK
票数 0
EN

Stack Overflow用户

发布于 2020-10-22 14:41:35

GNU awk有regex字段分隔符,因此只需要分隔列的多个空格即可。

代码语言:javascript
复制
awk '/Linux/ { print "The file \""$1"\" is in "$2"." }' FS="   *" test.txt

info gawk fieldwidths说,它还提供了固定宽度的字段,您可以使用破折号线的长度来设置动态字段。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64473364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档