始终在grep中包含第一行

jho*_*ack 43 bash grep

我经常在第一行使用列名grep CSV文件.因此,我希望grep的输出始终包含第一行(获取列名称)以及与grep模式匹配的任何行.做这个的最好方式是什么?

kev*_*kev 49

SED:

sed '1p;/pattern/!d' input.txt
Run Code Online (Sandbox Code Playgroud)

AWK:

awk 'NR==1 || /pattern/' input.txt
Run Code Online (Sandbox Code Playgroud)

grep1:

grep1() { awk -v pattern="${1:?pattern is empty}" 'NR==1 || $0~pattern' "${2:?filename is empty}"; }
Run Code Online (Sandbox Code Playgroud)


Eya*_*vin 12

另外一个选择:

$ cat data.csv | (read line; echo "$line"; grep SEARCH_TERM)
Run Code Online (Sandbox Code Playgroud)

例子:

$ echo "title\nvalue1\nvalue2\nvalue3" | (read line; echo "$line"; grep value2)
Run Code Online (Sandbox Code Playgroud)

输出:

title
value2
Run Code Online (Sandbox Code Playgroud)


Dig*_*oss 10

您可以为列名之一包含备用模式匹配。如果列被称为COL,那么这将起作用:

$ grep -E 'COL|pattern' file.csv
Run Code Online (Sandbox Code Playgroud)

  • 如果您没有严格控制第一行的内容,它也可能与文件后面的意外行匹配。 (3认同)

Ale*_*eys 10

grep并没有真正的行号概念,但是awk确实如此,所以这里输出行的示例包含"Incoming" - 以及第一行,无论它是什么:

awk 'NR == 1 || /Incoming/' foo.csv
Run Code Online (Sandbox Code Playgroud)

你可以制作一个脚本(有点过分但是).我创建了一个文件,grep + 1,并将其放入其中:

#!/bin/sh
pattern="$1" ; shift
exec awk 'NR == 1 || /'"$pattern"'/' "$@"
Run Code Online (Sandbox Code Playgroud)

现在可以:

./grep+1 Incoming
Run Code Online (Sandbox Code Playgroud)

编辑:删除了"{print;}",这是awk的默认操作.

  • 你好,亚历克斯——我喜欢脚本的想法,但可能会稍微修改它以实际使用 grep 而不是 awk 以便可以使用 grep 的其他命令行参数:`read; printf '%s\n' "$REPLY"; grep "$@"`。这种方法的主要问题是,如果 args 包含文件名,则需要将它们解析出来以进行本地处理。 (2认同)

Ada*_*iss 9

您可以使用sed而不是grep这样做:

sed -n -e '1p' -e '/pattern/p' < $FILE
Run Code Online (Sandbox Code Playgroud)

这将打印第一行两次,但是,如果它恰好包含该模式.

-n告诉我sed不要默认打印每一行.
-e '1p'打印第一行.
-e '/pattern/p'打印与模式匹配的每一行.

  • 使用`;`来sep:`sed -n'1p;/pattern/p'` (5认同)
  • `sed'1b;/pattern /!d'`会解决'打印第一行两次'的问题. (3认同)