棘手的 grep 命令

棘手的 grep 命令

我有一个文本文件,其中包含空格分隔的数据行。

例子:

B  345678  2005-12-21  4174  1  62  11111 16543 1911  786543,45

然而,空格有点不一致,有时我怀疑也有一些添加的选项卡。我需要找到一个在“62”之前截断该行的方法,“62”是每行中总是出现的数字,有时后面跟着一个 5 位数字,然后总是后面跟着另一个 5 位数字。我还在 62 之前添加了空格,以尽量减少不匹配的风险。

到目前为止我想出了这个:

grep " 62 [1-9][0-9][0-9][0-9][0-9] " file

这只会给出有时出现 5 位数字的行。我需要一种方法来 grep 62,后跟可选的 5 位数,然后是强制的 5 位数。

这可以做到吗?

/保罗

答案1

我需要一种方法来 grep 62,后跟可选的 5 位数,然后是强制的 5 位数。

这似乎与说 后面有一个或两个 5 位数字相同62,然后只匹配第一个就足够了。处理不同数量的空格很容易,我们可以使用␣+, 或[[:space:]]+来包含制表符。

所以,

grep -E ' 62 +[1-9][0-9]{4} '

或者

grep -E '[[:space:]]62[[:space:]]+[1-9][0-9]{4}[[:space:]]'

这当然会打印整行。如果您只需要从 62 开始的部分,请添加.*以匹配行尾并-o仅打印匹配的部分:

grep -o -E '[[:space:]]62[[:space:]]+[1-9][0-9]{4}[[:space:]].*'

答案2

您可以awk为此目的使用:

awk '{if (match($0, "(^[[:print:]]*[[:space:]]+)?(62([[:space:]]+[1-9][0-9]{4})?([[:space:]]+[[:print:]]*)?[[:space:]]+[1-9][0-9]{4}([[:space:]]*|[[:space:]]+[[:print:]]*)$)", a)!=0) print a[2];}' file.txt

这将匹配任何带有孤立 的行62,无论是在开头还是前面有任意数量的可打印字符,然后是一个或多个空格字符,然后是

  • 可选空格和五位数字
  • 可选任意数量的可打印字符
  • 强制空格和五位数字
  • 可选地,至少有一个空格和任意数量的可打印字符,或者行尾的空格

如果找到这样的模式,它将打印从 开始62到行尾的部分。

请注意,这不会挤压分隔的空格,因此“不一致的空格”将按原样复制到输出中。

答案3

...删除 62 之前的所有内容 (.....)

perl -pe 's/.*?(?= 62 +[1-9]\d{4} )//'

在哪里:

  • s/.*?...// - 意味着删除所有内容 = 不替换任何内容
  • .*?(?= 62) - 表示 62 之前的内容...

答案4

我建议

grep -E '\b62([[:blank:]]+[[:digit:]]{5}\b){1,2}'

其中\b是单词边界,允许“62”出现在行首或非单词字符(如空格)之后

相关内容