我有一个场景,数据位于这样的文件中。
数据 :
1234 2271 4423
8901 1234 2569
1234 5678 9107
1134 7896 6780
输出应该是:
1234 2271 4423
8901 1234 2569
1134 7896 6780
我需要搜索整行,如果发现任何相邻数字重复,则显示整行。 “相邻”数字可以用空格分隔(但不能用其他数字分隔)。
例如 :
1234 2271 4423 -> in this 2271 -> [2][2] 71 -> the 2 digit is adjacently repeated.
同样,还有另一个相邻重复的 -> 4423 -> [4][4]23
1134 7896 6780
In this also -> [1][1]34 and 789[6] [6]780
我得到了这个解决方案:有人可以解释它的确切含义以及任何其他简单的方法吗?请分享并提供正确的解释,以便我得到一些想法:
command 1 : grep '\([0-9]\) *\1'
command 2 : grep '\([0-9]\)\s*\1'
command 3 : grep '\(\d\)\s*\1'
command 4 : grep -e '([0-9])\1' -e '([0-9]) \1'
答案1
grep
如果我理解正确的话,这是 GNU 的可能性:
grep -P "([0-9])[[:blank:]]?\1" file
输出:
123422714423 8901 1234 2569 1134 7896 6780
答案2
虽然不像使用反向引用和问号量词那么有趣,但您可以使用管道和简单的正则表达式来完成此操作,其优点是更容易理解恕我直言。
tr -d ' ' | egrep '00|11|22|33|44|55|66|77|88|99' | sed -r 's/..../& /g'
或者您可以在 sed 中完成所有操作,但可读性较差:
sed -r 's/ //g;/00|11|22|33|44|55|66|77|88|99/!d;s/..../& /g'
它们的基本概念都是删除数字之间的空格,使用简单的正则表达式来匹配具有相邻数字的行,然后将空格放回以打印出来。
答案3
以下awk
程序应该有效:
awk '{buf=gensub(/ */,"","g",$0); split(buf,chars,""); last=chars[1];
for (i=2;i<=length(buf);i++) {if (chars[i]==last) {print; next}; last=chars[i]}}' test.txt
这将首先删除输入行中的所有空格并将结果存储在字符串中buf
。然后它将分成buf
单个字符的数组,chars
。将对其进行解析以查看是否找到连续的字符。如果是这样,则打印该行。
(这是一个不依赖正则表达式反向引用的解决方案)