![棘手的 grep 命令](https://linux22.com/image/164050/%E6%A3%98%E6%89%8B%E7%9A%84%20grep%20%E5%91%BD%E4%BB%A4.png)
我有一个文本文件,其中包含空格分隔的数据行。
例子:
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”出现在行首或非单词字符(如空格)之后