Awk - 每条匹配线的不同FS

时间:2016-04-14 05:02:05

标签: awk

我使用awk来匹配日志文件中的特定行。根据匹配的行,我想使用不同的FS。我想做一些类似我以下的事情,但它不起作用。有可能吗?

#!/usr/bin/gawk -f
if ( $0 ~ "good.morning" ) 
{ FS=","; print $1 }
if ( $0 ~ "good.evening" )
{ FS=";"; print $2 }

我意识到我可以在脚本的{BEGIN}部分设置FS。或者我可以在调用脚本时设置FS。但我希望能够更好地控制每个匹配记录的FS。

3 个答案:

答案 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等,但不要介意我。)