有没有办法用awk打印当前匹配的分隔符?
例如:
awk -F '["RESTART" | "FAILURE" | "WARNING" | [:blank:]]{2}' 'FNR > 4 { for (i=1; i<=NF; i++) print $i;}' file
示例输入
XX XXXX RESTART 6666 XX X
XXXX XXXX WARNING 8888 YYY YYY
XXX XXXX INFORM 7777 XXXX XX
示例输出(必须)
XX
XXXX
RESTART
6666
XX X
XXXX
XXXX
WARNING
8888
YYY YYY
XXX
XXXX
INFORM
7777
XXXX XX
示例输出(现在)
XX
XXXX
6666
XX X
XXXX
XXXX
8888
YYY YYY
XXX
XXXX
INFORM
7777
XXXX XX
我使用2个以上的空格作为列分隔符,但有些情况(RESTART 6666
)或(WARNING 8888
)其中两列没有两个空格分隔,这就是为什么我必须使用内容(RESTART
,WARNING
)作为分隔符,但如果我将内容用作分隔符,则不会显示,因此我想显示/打印使用的分隔符(如果是内容而不是空白)
主要问题是在一列中区分用作列分隔符的一个空格和用作字分隔符的一个空格。我无法影响我必须处理的文件。
答案 0 :(得分:1)
<强> AWK:强>
awk '{gsub(/ +|\t/,"\n")} {print}' file | awk '/RESTART|WARNING|FAILURE/{gsub(/ /,"\n")} {print}'
gsub(/ +|\t/,"\n")
:用换行符\n
替换“2个或多个空格OR \ t”。
这会将我们的文件转换为多行,其中每行可以由仅由单个空格分隔的多个单词组成。
/RESTART|WARNING|FAILURE/{gsub(/ /,"\n")
:如果该行包含这三个字中的一个,那么将空格替换为
\n
您还可以使用 sed :
sed "s/\s\s\+/\n/g; s/\(RESTART\|WARNING\|FAILURE\) /\1\n/g" file
对于较旧的sed版本(主要在MAC中):+可能不受支持,因此请将其修改为*
sed "s/\s\s\s*/\n/g; s/\(RESTART\|WARNING\|FAILURE\) /\1\n/g" file
s/\s\s\+/\n/g
:将2个或多个空格替换为单个\n
s/\(RESTART\|WARNING\|FAILURE\) /\1\n/g
:用\n
替换空格
三个例外
输入:
line one hello hello RESTART 6666 XX X
line two hello hello WARNING 8888 YYY YYY
line three hello hello INFORM 7777 XXXX XX
输出:
line one
hello hello
RESTART
6666
XX X
line two
hello hello
WARNING
8888
YYY YYY
line three
hello hello
INFORM
7777
XXXX XX
答案 1 :(得分:1)
这里有一个固定宽度字段的方法,可用于任何awk(当然,在Solaris上你应该使用/ usr / xpg4 / bin / awk的旧的awk / bin / awk除外):
$ cat tst.awk
{
# identify the fields:
nf = 0
f[++nf] = substr($0,1,8)
f[++nf] = substr($0,9,7)
f[++nf] = substr($0,16,8)
f[++nf] = substr($0,24,6)
f[++nf] = substr($0,30)
# remove leading/trailing white space from each field:
for (i in f) {
sub(/^[[:space:]]+/,"",f[i])
sub(/[[:space:]]+$/,"",f[i])
}
# print the fields:
for (i=1; i<=nf; i++) {
print NR, i, "<" f[i] ">"
}
print "---"
}
$ awk -f tst.awk file
1 1 <XX>
1 2 <XXXX>
1 3 <RESTART>
1 4 <6666>
1 5 <XX X>
---
2 1 <XXXX>
2 2 <XXXX>
2 3 <WARNING>
2 4 <8888>
2 5 <YYY YYY>
---
3 1 <XXX>
3 2 <XXXX>
3 3 <INFORM>
3 4 <7777>
3 5 <XXXX XX>
---
如果您在Solaris上使用nawk
,那么您必须将[[:space:]]
替换为[ \t]
,因为它早于POSIX字符类但只是不使用nawk,请使用/ usr / xpg4 / bin / awk。
如果此方法适合您,可以修改它以使用循环而不是5个显式substr()调用。
答案 2 :(得分:0)
也许你可以使用GNU awk&#39; split
与 seps 。 https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html告诉:
split(string,array [,fieldsep [,seps]])
seps是一个gawk扩展,seps [i]是array [i]和array [i + 1]之间的分隔符。