![如何在较长的字符串中找到变化的子字符串的起始位置](https://linux22.com/image/80858/%E5%A6%82%E4%BD%95%E5%9C%A8%E8%BE%83%E9%95%BF%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%BE%E5%88%B0%E5%8F%98%E5%8C%96%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E8%B5%B7%E5%A7%8B%E4%BD%8D%E7%BD%AE.png)
我将这些 200 多个字符长的字符串存储在一个文件中。在每个字符串中,都存在一个模式,例如##XXX###XXXX
其中#
是 0 到 9 之间的数字,X
是 A 到 Z 之间的大写或小写字符。前导和尾随字符可以是任何可打印字符,包括空格,但[0-9]
、[a-z]
和除外[A-Z]
。而且这个字符串的长度也不固定,但不少于180个字符,大部分都超过200个。
我所需要的只是较长字符串中模式的起始位置,就像 perl 中的索引函数返回的那样。我需要注意的是,这个系统上没有 perl,没有额外的软件安装机会。
到目前为止,我能想到的是从字符串的第一个字符开始,检查我得到的字符是否是数字。如果是,请检查第二个是否是数字。到目前为止,依此类推...通过使用级联 if 语句重复直到满足所有 12 个字符,如果在计数达到 12 之前比较链中的条件返回不满足要求的字符,则中断循环。
我想知道是否可以使用正则表达式或不使用正则表达式来完成任何事情,从而消除 bash 下 12 个级联 if 语句的需要。是的,我可以使用 sed 和 awk,如果它们能让生活更轻松的话。
答案1
< your_file \
tr -c \[:alnum:] '[\n*]' |
grep -n ............
...大概?strings
也非常方便...
< your_file \
tr -c \[:alnum:] '[\0*]' |
strings -n12 -td
答案2
没有调用外部工具(更快?):
while IFS= read -r a; do
head=${a%%[[:alnum:]]*}
tail=${a##*[[:alnum:]]}
a=${a##"$head"}
b=${a%%"$tail"}
printf '%4d <%s>\n' "${#head}" "$b"
done < file.csv
答案3
awk 有一个match
函数可以做一些听起来像你想要的事情
awk '{ print match($0, /[0-9][0-0]rest_of_your_pattern/) }' your_file
如果未找到匹配项,则返回匹配项0
(并打印)。