【问题标题】:sed/awk - return rows that match certain strings at the second columnsed/awk - 在第二列返回匹配某些字符串的行
【发布时间】:2016-12-15 22:32:21
【问题描述】:

我在 HDFS 中有一个 csv 文件,我正在使用 fread() 将其读入 R。数据如下所示:

Date       Code   Value  TransactionID
2016-01-01 769    123    16U11863C2MS0000337625C1
2016-02-01 2MS-US 456    16U11863C2MS0000337626C1
2016-03-01 E9E-US 789    16U11863C2MS0000337627C1

我想使用sed 仅读取代码为“2MS-US”或“769”的行。我没有使用grep,因为它不保留标题。我试过了:

fread("hadoop fs -text /path/to/file.csv | sed -n '1p;/^[0-9]*-[0-9]*-[0-9]* 2MS-US/p; /^[0-9]*-[0-9]*-[0-9]* 769/p'", fill=TRUE)

但这会返回零行。我猜我有错误的正则表达式,但不知道如何解决。

我也尝试过使用awk,但只是用条件过滤没有任何运气:

fread("hadoop fs -text /path/to/file.csv | awk '$2 == 2MS-US'", fill=TRUE)

返回以下错误信息:

fread 中的错误(....) 期望 2 列,但第 5293 行在处理所有列后包含文本。使用 fill=TRUE 重试。

任何关于sedawk(如果awk 能够保留标题)的修复建议将不胜感激!

编辑:

感谢@amaurea 以及thread 的帮助,我已经能够通过以下代码实现我的目标:

fread("/usr/bin/hadoop fs -text /path/to/file.csv | awk  -F '\"*,\"*' 'FNR==1||$2==\"2MS-US\"||$2==\"769\"'"

如果我错了,请纠正我,但在我看来,当使用awk 处理 csv 文件时,需要-F '\"*,\"*',而文本文件则不然。

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    您的 awk 脚本中的引用似乎存在问题。 2MS-US 需要引用。这个 awk 命令对我有用:

    awk 'FNR==1||$2=="2MS-US"||$2=="769"' hdfs.txt
    

    其中 hdfs.txt 是包含示例内容的文件。这输出

    Date       Code   Value  TransactionID
    2016-01-01 769    123    16U11863C2MS0000337625C1
    2016-02-01 2MS-US 456    16U11863C2MS0000337626C1
    

    我认为这是你想要的。但是,由于您在带引号的字符串中调用 awk,因此您可能需要转义 awk 命令中的双引号,以避免与 fread 中的双引号发生冲突,如下所示:

    fread("hadoop fs -text /path/to/file.csv | awk 'FNR==1||$2==\"2MS-US\"||$2==\"769\"'", fill=TRUE)
    

    虽然真的,人们希望直接在 R 中过滤表格会更干净。

    编辑:由于您仍然遇到问题,这是一个适合我的小测试用例,您可以直接在终端中运行:

    $ cat <<HERE > hdfs.txt
    Date       Code   Value  TransactionID
    2016-01-01 769    123    16U11863C2MS0000337625C1
    2016-02-01 2MS-US 456    16U11863C2MS0000337626C1
    2016-03-01 E9E-US 789    16U11863C2MS0000337627C1
    HERE
    $ cat <<HERE > test.r
    library(data.table)
    fread("awk 'FNR==1||$2==\"2MS-US\"||$2==\"769\"' hdfs.txt")
    $ R -q -f test.r
    > library(data.table)
    > fread("awk 'FNR==1||$2==\"2MS-US\"||$2==\"769\"' hdfs.txt")
             Date   Code Value            TransactionID
    1: 2016-01-01    769   123 16U11863C2MS0000337625C1
    2: 2016-02-01 2MS-US   456 16U11863C2MS0000337626C1
    >
    

    【讨论】:

    • 我像这样在awk 命令中转义了双引号:fread("hadoop fs -text /file.csv | awk 'FNR==1||$2==\"2MS-US\"||$2==\"769\"'", fill=TRUE),但它返回了一个零行表
    • @JJ.Y:我没有 hadoop,所以我无法测试你命令的第一部分,但这对我有用fread("awk 'FNR==1||$2==\"2MS-US\"||$2==\"769\"' hdfs.txt")。它返回一个包含两行和一个标题的表。你能在没有 hadoop 的情况下尝试一下,看看你能不能重现我的结果?
    • 我选择在加载数据之前对其进行过滤,因为我正在同时读取多个文件,这将导致我最不使用的巨大表(>10m 行)部分。
    • 嗯....您是否也熟悉sed?也许我们可以看看这是否有效。提前致谢!
    • @JJ.Y:你试过我的测试用例了吗?
    猜你喜欢
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多