[英]awk define field pattern
我正在寻找一种方法,使用awk将以下文本拆分为适当的列。
我有
[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'
[2013-06-17 13:30] [PACMAN] reinstalled cups (1.6.2-2)
所以,关于:
[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'
我想要:
$1 to be [2013-06-17 13:30]
$2 to be [PACMAN]
$3 to be Running
$4 to be 'pacman -S cups'
对于:
[2013-06-17 13:30] [PACMAN] reinstalled cups (1.6.2-2)
我想要:
$1 to be [2013-06-17 13:30]
$2 to be [PACMAN]
$3 to be reinstalled
$4 to be cups (1.6.2-2)
我做了很多谷歌搜索,找不到任何东西,我对awk很新
(以下内容似乎特定于GNU awk
; BSD awk
不支持将子组捕获到数组中。)
在这种情况下,您可能希望将整个字符串与特定的正则表达式进行匹配,而不是依赖于awk
的字段拆分。
$ echo "[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'" | awk '
{
match($0, "^(\\\[.*\\\]) (\\\[.*\\\]) ([a-zA-Z]*) (.*)$", a);
$1=a[1];
$2=a[2];
$3=a[3];
$4=a[4];
print $2
}'
[PACMAN]
调用match
,数组a
将填充$0
中与正则表达式匹配的文本。 第0个元素是整个匹配字符串,其余元素设置为正则表达式中对应的带括号的组。
可能有更好的方法来编写正则表达式; 我得到一个警告\\[
被视为一个普通的[
,但总的来说它似乎工作。
对于不优雅的方法,请参见下面的第四个单线。 有用!! 但你可能不想接受我的回答。 该命令很嘈杂,您可能需要将注释添加为“文档”以使其可维护。 出于这个原因,我也把它作为.awk
文件包含在下面:-)
尽管如此,即使文件的格式相当简单,我认为最好的方法是使用正则表达式作为@chepner注释。如果只是因为它记录了自己。
~/$ cat test.txt
[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'
[2013-06-17 13:30] [PACMAN] reinstalled cups (1.6.2-2)
1)第一栏:
~/$ awk -F '[\]]' '{print $1"]"}' test.txt
[2013-06-17 13:30]
[2013-06-17 13:30]
2)第一列和第二列:
~/$ awk -F '[\]]' '{print $1"]" $2"]" }' test.txt
[2013-06-17 13:30] [PACMAN]
[2013-06-17 13:30] [PACMAN]
3)所有三个:
~/$ awk -F '[\]]' '{print $1"]" $2"]" $3}' test.txt
[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'
[2013-06-17 13:30] [PACMAN] reinstalled cups (1.6.2-2)
4)与上面相同,但将第三个字段拆分为数组a
以便分别打印Running
或reinstalled
。 从第一个元素的length
开始,从offset( os
)开始打印数组a
( substr
)的子字符串。
~/$ awk -F ']' '{split($3,a," "); os=(length(a[1])+2) ; print $1"]" $2"] " a[1]" " substr($3,os) }' test.txt
[2013-06-17 13:30] [PACMAN] Running 'pacman -S cups'
[2013-06-17 13:30] [PACMAN] reinstalled cups (1.6.2-2)
这是BSD awk
所以它应该适用于OSX。
# split.awk ... run with: awk -f split.awk data.txt
BEGIN{
FS="]" # Make the field separator be "]"
}
{
# Split the third field into array "a"
split($3,a," ")
os=(length(a[1])+2)
# Print the first two fields and a substring of array "a" (substr)
# starting at offset ("os") taken from the length of the first element
# right adjusted for two whitespaces.
print $1"]" $2"] " a[1]" " substr($3,os)
}
HTH。
在你的例子中陈述的第3和第5场(以及缺少第4场)你想要什么有一点混乱。
第一种方式:我的试验是基于引入一个新的分隔符,我们想要分开的领域...
命令:
~/so_test> cat ztmp_bk | sed -n 's/]/]^/gp'| awk -F"^" '{print $1 "==" $2 "==" $3 }'
输出:(由“==”标识的字段)
[2013-06-17 13:30]== [PACMAN]== Running 'pacman -S cups'
[2013-06-17 13:30]== [PACMAN]== reinstalled cups (1.6.2-2)
第二种方式:
另一种方法是将文件分割成部分并再次为第3个文件执行,直到我们得到所需的单个coloumn然后我们可以使用使用用户定义的分隔符的粘贴合并它们...
如下所示:(相当粗糙,但你明白了!)
Kaizen ~/so_test/test $ cat ztmp | sed -n 's/]/]^/gp'| awk -F"^" '{print $1 "^" $2}' > ztmp1 ;
Kaizen ~/so_test/test $ cat ztmp | awk -F" " '{print $4 "^" $5 $6 $7}' > ztmp2 ;
Kaizen ~/so_test/test $ paste -d^ ztmp1 ztmp2 > ztmpF ;
输出:这会给你一个^分隔的新文件,因此你以前的awk命令现在可以在这个文件上工作
Kaizen ~/so_test/test $ cat ztmpF
[2013-06-17 13:30]^ [PACMAN]^Running^'pacman-Scups'
[2013-06-17 13:30]^ [PACMAN]^reinstalled^cups(1.6.2-2)
Kaizen ~/so_test/test $ cat ztmpF | awk -F"^" '{print "first field:" $1 "\n" "second field:" $2 "\n" "third field:" $3 "\n" "forth field:" $4 "\n" }'
first field:[2013-06-17 13:30]
second field: [PACMAN]
third field:Running
forth field:'pacman-Scups'
first field:[2013-06-17 13:30]
second field: [PACMAN]
third field:reinstalled
forth field:cups(1.6.2-2)
这有帮助吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.