我需要确定字符串中字符的位置。
例如,字符串是RAMSITALSKHMAN|1223333
。
grep -n '[^a-zA-Z0-9\$\~\%\#\^]'
Run Code Online (Sandbox Code Playgroud)
如何找到|
给定字符串中的位置?
run*_*uhl 33
您可以使用-b
获取字节偏移量,它与简单文本的位置相同(但不适用于 UTF-8 或类似的)。
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|'
14:|
Run Code Online (Sandbox Code Playgroud)
在上面,我使用-a
switch 告诉 grep 将输入用作文本;在对二进制文件进行操作时是必需的,并且-o
只输出匹配字符的开关。
如果您只想要位置,则可以使用 grep 仅提取位置:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' | grep -oE '[0-9]+'
14
Run Code Online (Sandbox Code Playgroud)
如果您得到奇怪的输出,请检查 grep 是否启用了颜色。您可以通过传递--colors=never
给 grep 或在 grep 命令前加上 a \
(这将禁用任何别名)来禁用颜色,例如:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' --color=never | \grep -oE '^[0-9]+'
14
Run Code Online (Sandbox Code Playgroud)
对于返回多个匹配项的字符串,通过管道head -n1
获取第一个匹配项。
请注意,我在上面同时使用了两者,并注意如果 grep 通过可执行文件(脚本或其他方式)“别名化”,后者将不起作用,只有在使用别名时。
Dig*_*uma 11
如果您使用的是bash shell,则可以使用纯粹的内置操作,而无需生成外部进程,例如grep或awk:
$ str="RAMSITALSKHMAN|1223333"
$ tmp="${str%%|*}"
$ if [ "$tmp" != "$str" ]; then
> echo ${#tmp}
> fi
14
$
Run Code Online (Sandbox Code Playgroud)
这使用参数扩展来删除|
任何字符串出现的所有后续内容并将其保存在临时变量中。然后只需测量临时变量的长度即可获得 的索引|
。
请注意,if
正在检查|
原始字符串中是否存在。如果不是,那么临时变量将与原始变量相同。
另请注意,这提供了从零开始的索引,|
在索引 bash 字符串时通常很有用。但是,如果您需要基于一的索引,那么您可以这样做:
$ echo $((${#tmp}+1))
15
$
Run Code Online (Sandbox Code Playgroud)
cuo*_*glm 10
尝试:
printf '%s\n' 'RAMSITALSKHMAN|1223333.' | grep -o . | grep -n '|'
Run Code Online (Sandbox Code Playgroud)
输出:
15:|
Run Code Online (Sandbox Code Playgroud)
这将为您提供索引为 1 的位置。
您可以使用 awk 的index
函数返回匹配发生的字符位置:
echo "RAMSITALSKHMAN|1223333"|awk 'END{print index($0,"|")}'
15
Run Code Online (Sandbox Code Playgroud)
如果您不介意使用 Perl 的index
函数,它可以处理报告零次、一次或多次出现的字符:
echo "|abc|xyz|123456|zzz|" | \
perl -nle '$pos=-1;while (($off=index($_,"|",$pos))>=0) {print $off;$pos=$off+1}'
Run Code Online (Sandbox Code Playgroud)
仅为了便于阅读,管道已分为两行。
只要找到目标字符,index
就会返回一个基于零 (0) 的正值。因此,字符串“abc|xyz|123456|zzz|” 解析后返回位置 0、4、8、15 和 19。