GREP 匹配其他数据中的 6-7 位数字

GREP 匹配其他数据中的 6-7 位数字

我正在尝试创建一个正则表达式来匹配 6 或 7 位长的数字字符串。

[0-9]{6,7} 这可行,但我不希望匹配长度超过 7 位数字的字符串。

请参阅下面的示例数据,其中我需要匹配的粗体数字。一些 6-7 位字符串的开头和结尾有各种字符(换行符、制表符、空格),我也不想匹配开头有两个或多个 0 的字符串。

1139055_00000000000000.jpg1139065_00000000000000.jpg

12345678 1045977_00000000000000.jpg

_1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd 标题:0582457_00_CC 0123456789 标题:6844393_50_v2 标题:6844393_50_v2.psd 0001456789 0000001546800000

总数:14 6582457_00_C 5142090_00_c ID:1178287标题:6582457_00_CC 标题:6844393_50_v2 ID:1178288标题:_0042090_00_cc __6771292_00_cc

输入示例:

1139055_00000000000000.jpg 1139065_00000000000000.jpg
12345678 1045977_00000000000000.jpg
_1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd Title: 0582457_00_CC 0123456789 Title: 6844393_50_v2 Title: 6844393_50_v2.psd 0001456789 0000001546800000
Total: 14 6582457_00_C 5142090_00_c Id: 1178287 Title: 6582457_00_CC Title: 6844393_50_v2 Id: 1178288 Title: _0042090_00_cc __6771292_00_cc

预期输出:

1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292

任何帮助表示赞赏。

答案1

所以,总而言之,你想要匹配小数位,其中至少一位必须非零,后跟另一位四五个十进制数字,前面或后面没有其他数字?

如果是这样,请在 PCRE 模式下使用 GNU grep 进行查找:

grep -P '(?<!\d)([1-9][0-9]|[0-9][1-9])[0-9]{4,5}(?!\d)'

使用以下命令测试您的输入-o

$ grep -Po '(?<!\d)([1-9][0-9]|[0-9][1-9])[0-9]{4,5}(?!\d)' << \EOF
    1139055_00000000000000.jpg 1139065_00000000000000.jpg

    12345678 1045977_00000000000000.jpg

    _1162679.jpg ID:1099695_20230615142941.jpg 1099692_20230615142939.jpg 1162700_00000000000000.jpg 012456.psd Title: 0582457_00_CC 0123456789 Title: 6844393_50_v2 Title: 6844393_50_v2.psd 0001456789 0000001546800000

    Total: 14 6582457_00_C 5142090_00_c Id: 1178287 Title: 6582457_00_CC Title: 6844393_50_v2 Id: 1178288 Title: _0042090_00_cc __6771292_00_cc
EOF
1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292

答案2

假设您只想要一个简单的解决方案,而不是要求它是单个正则表达式,那么使用 GNU awk (在大多数 Unix 机器上可用或可安装)来处理多字符RS

$ awk -v RS='[^0-9]+' '!/^00/ && /^.{6,7}$/' file
1139055
1139065
1045977
1162679
1099695
1099692
1162700
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292

或者在每个 Unix 机器上的任何 shell 中使用任何 awk,你可以这样做:

awk -F'[^0-9]+' '{ for (i=1; i<=NF; i++) if ( ($i !~ /^00/) && (length($i) ~ /^[67]$/) ) print $i }' file

另外,对于任何用于正则表达式间隔表示法的 POSIX awk(我相信包括 MacOS 上的 BSD awk){6,7},您可以使用前面对 awk 的调用将所有非数字字符串转换为换行符,以便默认值RS随后生效:

awk '{gsub(/[^0-9]+/,RS)} 1' file | awk '!/^00/ && /^.{6,7}$/'

或者,再次使用任何 awk:

awk '{gsub(/[^0-9]+/,RS)} 1' file | awk '!/^00/ && (length() ~ /^[67]$/)'

如果您愿意并且可以在您使用的版本中使用,您可以使用tr -cs '0-9' '\n' < file或 类似的代替。awk '{gsub(/[^0-9]+/,RS)} 1' filetr

答案3

grep、sed 和 awk 链提供了您需要的列表:

$ egrep '[0-9]*' -o Q768182 | sed '/00/d' | awk 'length>5 && length <8'
1139055
1139065
1045977
1162679
1099695
1099692
012456
0582457
6844393
6844393
6582457
5142090
1178287
6582457
6844393
1178288
6771292

答案4

这个正则表达式似乎可以为您的示例完成工作:

(?:[^0-9]|^)((?:0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5})(?:[^0-9]|$)
  • (?:[^0-9]|^):确保其行首或前面的字符不是数字
  • ((?:0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5}):获取开头不带00的6-7位数字
  • (?:[^0-9]|$):确保行尾或后面的字符不是数字

你可以用它来玩https://regex101.com/r/scZc9q/1

由于第一个/最后一个字符将位于匹配的字符串中,因此最简单的使用方法grep是使用以下命令删除这些字符sed

grep -oE '([^0-9]|^)(0[1-9]|[1-9]0|[1-9]{2})[0-9]{4,5}([^0-9]|$)' tmp | sed 's/[^0-9]//g'

相关内容