使用 awk 重新格式化文本文件的列

使用 awk 重新格式化文本文件的列

好吧,既然这是一个复杂的问题,我会解释清楚。我得到的文件内容如下所示:

$ 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

之后,我用数据替换里面的数据File4File3意味着没有括号的数据“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都列出来了,其他的没有显示出来(归档最后一列数据),

答案1

我不知道你为什么要左右复制东西。简单的事情是

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

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

在这之间我们打印

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

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

答案2

sed

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

awk变化

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

答案3

简单的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 Lispawk 宏音译awk解决方案:

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

字段位于f列表中,索引是从零开始的。

答案4

$1,$2,...当字段已经包含您想要使用的确切字符串时,使用 awk 是最简单的。字段分隔符如果包含多个字符,则被解释为正则表达式。我们不需要执行任何搜索和替换或子字符串操作来摆脱{花括号}。我们只是将它们算作分隔符的一部分。

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

使用printf代替print也可以更容易地查看字符串的格式,但如果您想使用print "-"$2,$5" + "$4";"代替printf("-%s %s + %s ;\n", $2, $5, $4),这是一个选项。

相关内容