我使用awk来匹配日志文件中的特定行。根据匹配的行,我想使用不同的FS。我想做一些类似我以下的事情,但它不起作用。有可能吗?
#!/usr/bin/gawk -f
if ( $0 ~ "good.morning" )
{ FS=","; print $1 }
if ( $0 ~ "good.evening" )
{ FS=";"; print $2 }
我意识到我可以在脚本的{BEGIN}部分设置FS。或者我可以在调用脚本时设置FS。但我希望能够更好地控制每个匹配记录的FS。
答案 0 :(得分:2)
您的问题是FS
通常用于将行分隔为字段,因为它已被读入。 awk
的基本流程是:
您可以通过成绩单看到:
pax> ( echo '1 2 3'; echo '4;5;6' ) >inputdata
pax> awk '{FS=";"; print $2} inputdata
2
5
在运行正文之前,1 2 3
行被分隔为字段,因此FS
的设置只会影响后续行。
所以,是的,你可以在行级别更改字段分隔符,但通常必须在读取行之前完成(例如在处理上一个行。)
但是,实际强制awk
重新解析该行的方法有点棘手,只需将其设置为等于自身即可。首先,我们更改输入中的两个行,以使用;
作为字段分隔符:
pax> ( echo '1;2;3'; echo '4;5;6' ) >inputdata
我们运行您最初认为可能有效的脚本样式:
pax> awk '{FS=";"; print $2}' inputdata
5
从第一个示例中可以看出,行1;2;3
被放入单个字段中,因为空格被用作分隔符。因此,第二个字段是空白的。与之对比:
pax> awk '{FS=";"; $0 = $0; print $2}' inputdata
2
5
在更改$0 = $0
变量后,将FS
添加到混合中会导致awk
使用修改后的分隔符重新解析该行,从而重新填充$1
,{{1等等。
答案 1 :(得分:2)
是的,您可以通过以下方式执行此操作:
package afester.javafx.examples.fxml;
import java.net.URL;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class FxmlViewer extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
URL location = getClass().getResource("FxmlSample.fxml");
BorderPane root = FXMLLoader.load(location);
stage.setScene(new Scene(root));
stage.show();
}
}
$ cat data
ONE 1 I
TWO 2 II
THREE:3:III
FOUR:4:IV
FIVE:5:V
SIX 6 VI
SEVEN 7 VII
$ ./awkscript data
I
II
III
IV
V
VI
VII
$
如下:
awkscript
#!/bin/awk -f
{
if ( $0 ~ /:/ )
{
FS=":";
$0=$0
}
else
{
FS=" ";
$0=$0
}
#print the third field, whatever format
print $3
}
根据当前$0=$0
重新评估字段。
答案 2 :(得分:1)
由于必须在Awk读取行之前将FS
设置为您想要的值,因此最简单的解决方法可能是明确split
。
#!/usr/bin/gawk -f
/good.morning/ { split($0,a,","); print a[1] }
/good.evening/ { split($0,a,";"); print a[2] }
(我猜你真的是good\.morning
等,但不要介意我。)