sed / awk - 返回与第二列

时间:2016-08-09 18:42:39

标签: awk sed

我在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个cols,但是5293行包含处理完所有cols后的文本。再次尝试使用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 '\"*,\"*',而文本文件不是这种情况。

1 个答案:

答案 0 :(得分: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
>