关于awk的问题


9

好的,因为这是一个复杂的问题,所以我将对其进行清楚的解释。我得到的文件内容如下所示:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

我想要的输出

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

首先,我尝试从中取出最后一列File1并通过 sed 's/[{}//g' File1 > File3

之后,我将的全部内容复制File1到一个新的File4

cp File1 File4

之后,我替换数据内的File4与所述File3数据(装置中的数据,而不托架一个“ File1最后一列的一个”)

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

输出应该是这样的

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

最后,我尝试

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

但是结果并没有如我所愿的那样出来,只有类似的数据MNB都被列出了,其他的都没有出现(文件最后一列数据),


您在使用gnu awk吗?
2013年

我不确定您的意思。但是我只是一个接触awk的新手。这是我需要完成的任务,我会根据对awk的理解,尽力一步一步地做到这一点。
heng960407

1
类型awk --version,结果如何?
123

2
请更改标题,使其更符合您的问题。这将使将来有类似问题的其他人更容易找到它。目前,“关于awk的问题”非常笼统。
汤姆·费内奇

Answers:


16

我不知道您为什么要左右复制内容。简单的事情是

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

我把-开始放在开头;,然后放在结尾。

在我们之间打印

  • $2 因为我们想要它。
  • 的子字符串$5,它是没有第一个和最后一个字符的字符串。我们从第2个位置开始跳过第一个字符(awk对此一直很陌生),而仅选择一个比原始字符短两个字符的子字符串来省略最后一个字符$5
  • +,因为我们需要它
  • 然后 $4

但是,我不确定所有这些字符串函数是否都特定于GNU awk。


substr(string, 2)返回子从第二个字符,如启动cut -c2-tail -n +2sed '2,$'...什么是如此奇怪?
斯特凡Chazelas

3
该命令是标准命令,甚至可以与awk70年代的原始命令一起使用。
斯特凡Chazelas

@StéphaneChazelas:啊,我一直在等你:-)通常我们从0开始计数,这意味着索引2是第三个位置,但是这里的第二个位置是在索引2。感谢澄清剩下的GNU问题。
Bananguin

@Bananguin,在上面的几个示例中所示的Unix Shell和实用程序中,我们从1开始,而不是0。最值得注意的例外是ksh的数组和$ {var:offset}(均由bash复制)。所有其他外壳程序数组均从1开始。另请参见是否有理由将Zsh数组的第一个元素索引为1而不是0?
斯特凡Chazelas

7

sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

awk变化

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

简单的TXR工作:

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

使用TXR Lisp awk宏音译Awk解决方案:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

字段在f列表中,索引从零开始。


1
+1为最轻薄和最可爱的外观!该语言必须参加pcg(编程代码高尔夫)竞争
-Archemar

@Archemar TXR在打高尔夫球方面不能很好地竞争,因为专门设计了专门的语言来完成诸如为单个角色分配功能,然后可以将它们组合在一起以达到构图的目的。
卡兹(Kaz)


1
@Kaz某处有TXR教程吗?手册页似乎很大。与awk相比,它的性能如何?
bli

1
@bli GNU Awk在通过大文件进行基本字段拆分时的速度至少比TXR awk宏快30倍,TXR awk宏包含220多行 解释代码,包括用于将输入源处理为记录和字段的整个循环。
卡兹(Kaz)2016年

3

$1,$2,...字段中已经包含您要使用的确切字符串时,使用awk最简单。如果字段分隔符包含多个字符,则将其解释为正则表达式。我们不需要执行任何搜索和替换或子字符串操作即可摆脱{curly braces}。我们只是将它们视为定界符的一部分。

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

使用printf代替print还使查看字符串的格式变得容易一些,但是如果要print "-"$2,$5" + "$4";"代替printf("-%s %s + %s ;\n", $2, $5, $4),则可以选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.