Answers:
您可以使用-b
获取字节偏移量,该偏移量与简单文本的位置相同(但对于UTF-8或类似字符而言则不同)。
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|'
14:|
在上面,我使用-a
开关告诉grep使用输入作为文本;对二进制文件进行操作时必需,并且-o
开关仅输出匹配的字符。
如果只需要该位置,则可以使用grep仅提取该位置:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' | grep -oE '[0-9]+'
14
如果输出奇怪,请检查grep是否启用了颜色。您可以通过传递--colors=never
给grep或在grep命令前加上一个前缀\
(这将禁用任何别名)来禁用颜色,例如:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' --color=never | \grep -oE '^[0-9]+'
14
对于返回多个匹配项的字符串,请通过管道进行操作head -n1
以获得第一个匹配项。
请注意,我在上文中同时使用了两者,请注意,如果仅通过使用别名通过可执行文件(脚本或其他方式)对grep进行了“别名”,则后者将不起作用。
2
;)
^
:)
0:|
了输出-因为0 |
是找到行的开头的字节位置。
grep (GNU grep) 2.27
。您也许正在使用OS X?
尝试:
printf '%s\n' 'RAMSITALSKHMAN|1223333.' | grep -o . | grep -n '|'
输出:
15:|
这将为您提供基于索引-1的职位。
printf '%s\n' '|' | grep -o . | grep -n '|'
打印1
,0
与预期不符。
如果您使用的是bash shell,则可以使用纯粹的内置操作,而无需生成诸如grep或awk之类的外部进程:
$ str="RAMSITALSKHMAN|1223333"
$ tmp="${str%%|*}"
$ if [ "$tmp" != "$str" ]; then
> echo ${#tmp}
> fi
14
$
这使用参数扩展来删除|
任何字符串出现的所有跟随事件,并将其保存在临时变量中。然后,只需测量临时变量的长度以获得的索引即可|
。
注意,if
正在检查|
原始字符串中是否存在。如果不是,则临时变量将与原始变量相同。
还要注意,这提供了从零开始的索引,|
在为bash字符串建立索引时通常很有用。但是,如果您需要基于一个的索引,则可以执行以下操作:
$ echo $((${#tmp}+1))
15
$
您可以使用awk的index
函数以字符形式返回匹配发生的位置:
echo "RAMSITALSKHMAN|1223333"|awk 'END{print index($0,"|")}'
15
如果您不介意使用Perl的index
功能,则可以处理报告零次,一次或多次出现的字符:
echo "|abc|xyz|123456|zzz|" | \
perl -nle '$pos=-1;while (($off=index($_,"|",$pos))>=0) {print $off;$pos=$off+1}'
仅出于可读性考虑,管道已分为两行。
只要找到目标字符,就index
返回基于零(0)的正值。因此,字符串“ abc | xyz | 123456 | zzz |” 解析后返回位置0、4、8、15和19。
RAMSITALSKHMAN|1|223333
我们也可以使用“ expr match”或“ expr index”
expr match $ string $ substring,其中$ substring是RE。
echo `expr match "RAMSITALSKHMAN|1223333" '[A-Z]*.|'`
而上面的位置将给您,因为它返回匹配的子字符串的长度。
但更具体地说,搜索索引:
mystring="RAMSITALSKHMAN|122333"
echo `expr index "$mystring" '|'`
awk
可以修改解决方案以在文件的每一行上报告此信息(您要做的就是END
从JRFerguson的答案中删除从未真正需要的,而Avinash Raj的确已经做到了) ; 然而,要使用expr
解决方案来做到这一点,您将需要添加一个显式循环(我所看到的,Gnouc的答案根本不容易适应此操作),并且(2)awk
解决方案可以适应于报告所有比expr
解决方案更容易在每一行中进行匹配(实际上,Avinash Raj's已经做到了)。
echo `...`
在这里使用?
$ echo 'RAMSITALSKHMAN|1223333'| awk 'BEGIN{ FS = "" }{for(i=1;i<=NF;i++){if($i=="|"){print i;}}}'
15
通过将字段分隔符设置为空字符串,awk将记录中的单个字符转换为单独的字段。
一些替代方案包括:
与Gnouc的答案类似,但带有shell:
echo 'RAMSITALSKHMAN|1223333' |
tr -c \| \\n |
sh
sh: line 15: syntax error near unexpected token `|
sh: line 15: `|'
用sed
和dc
可能跨越多个行:
echo 'RAMSITALSKHMAN|1223333' |
sed 's/[^|]/1+/g;s/|/p/;1i0 1+' |dc
15
与$IFS
...
IFS=\|; set -f; set -- ${0+RAMSITALSKHMAN|1223333}; echo $((${#1}+1))
这也将告诉你如何许多有像...
echo $(($#-1))