Respuestas:
Puede usar -b
para obtener el desplazamiento de bytes, que es lo mismo que la posición para texto simple (pero no para UTF-8 o similar).
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|'
14:|
En lo anterior, uso el -a
interruptor para decirle a grep que use la entrada como texto; necesario cuando se opera en archivos binarios, y el -o
interruptor para generar solo los caracteres coincidentes.
Si solo desea la posición, puede usar grep para extraer solo la posición:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' | grep -oE '[0-9]+'
14
Si obtiene resultados extraños, verifique si grep tiene colores habilitados. Puede deshabilitar los colores pasando --colors=never
a grep, o prefijando el comando grep con un \
(que deshabilitará cualquier alias), por ejemplo:
$ echo "RAMSITALSKHMAN|1223333" | grep -aob '|' --color=never | \grep -oE '^[0-9]+'
14
Para una cadena que devuelve múltiples coincidencias, canalice head -n1
para obtener la primera coincidencia.
Tenga en cuenta que uso ambos en lo anterior, y tenga en cuenta que este último no funcionará si grep está "aliasado" a través de un ejecutable (script u otro), solo cuando use alias.
2
;)
^
:)
0:|
como salida, porque 0 es la posición de byte del comienzo de la línea donde |
se encuentra.
grep (GNU grep) 2.27
. ¿Estás quizás usando OS X?
Tratar:
printf '%s\n' 'RAMSITALSKHMAN|1223333.' | grep -o . | grep -n '|'
salida:
15:|
Esto le dará la posición con índice basado-1.
printf '%s\n' '|' | grep -o . | grep -n '|'
impresiones 1
, no 0
como se esperaba.
Si está utilizando el shell bash , puede utilizar operaciones puramente integradas sin la necesidad de generar procesos externos como grep o awk :
$ str="RAMSITALSKHMAN|1223333"
$ tmp="${str%%|*}"
$ if [ "$tmp" != "$str" ]; then
> echo ${#tmp}
> fi
14
$
Utiliza una expansión de parámetros para eliminar todas las ocurrencias de |
seguimientos de cualquier cadena y guardarla en una variable temporal. Es solo una cuestión de medir la longitud de la variable temporal para obtener el índice |
.
Tenga en cuenta que if
está comprobando si |
existe en absoluto en la cadena original. Si no es así, la variable temporal será la misma que la original.
Tenga en cuenta también que esto proporciona un índice de base cero |
que generalmente es útil cuando se indexan cadenas bash. Sin embargo, si necesita el índice basado en uno, puede hacer esto:
$ echo $((${#tmp}+1))
15
$
Puede usar la index
función de awk para devolver la posición en los caracteres donde se produce la coincidencia:
echo "RAMSITALSKHMAN|1223333"|awk 'END{print index($0,"|")}'
15
Si no le importa usar la index
función de Perl , esto maneja informar cero, una o más ocurrencias de un personaje:
echo "|abc|xyz|123456|zzz|" | \
perl -nle '$pos=-1;while (($off=index($_,"|",$pos))>=0) {print $off;$pos=$off+1}'
Solo para facilitar la lectura, la tubería se ha dividido en dos líneas.
Siempre que se encuentre el carácter objetivo, index
devuelve un valor positivo basado en cero (0). Por lo tanto, la cadena "abc | xyz | 123456 | zzz |" cuando se analiza devuelve las posiciones 0, 4, 8, 15 y 19.
RAMSITALSKHMAN|1|223333
También podemos hacerlo usando "expr match" o "expr index"
expr match $ string $ substring donde $ substring es un RE.
echo `expr match "RAMSITALSKHMAN|1223333" '[A-Z]*.|'`
Y arriba le dará la posición porque devuelve la longitud de la subcadena coincidente.
Pero para ser más específico para el índice de búsqueda:
mystring="RAMSITALSKHMAN|122333"
echo `expr index "$mystring" '|'`
awk
soluciones pueden modificarse trivialmente para informar esta información en cada línea de un archivo (todo lo que tiene que hacer es eliminar el END
, que nunca fue realmente necesario, de la respuesta de JRFerguson, y Avinash Raj ya lo hace) ; mientras que para hacer eso con la expr
solución, necesitaría agregar un ciclo explícito (y la respuesta de Gnouc no es fácilmente adaptable para hacer eso, eso puedo ver), y (2) las awk
soluciones pueden adaptarse para informar todos los coincide en cada línea algo más fácilmente que la expr
solución (de hecho, Avinash Raj's ya lo hace también).
echo `...`
aquí?
$ echo 'RAMSITALSKHMAN|1223333'| awk 'BEGIN{ FS = "" }{for(i=1;i<=NF;i++){if($i=="|"){print i;}}}'
15
Al establecer el separador de campo como una cadena nula, awk convierte los caracteres individuales en el registro como campos separados.
Algunas alternativas incluyen:
similar a la respuesta de Gnouc, pero con el caparazón:
echo 'RAMSITALSKHMAN|1223333' |
tr -c \| \\n |
sh
sh: line 15: syntax error near unexpected token `|
sh: line 15: `|'
con sed
y dc
posiblemente abarcando múltiples líneas:
echo 'RAMSITALSKHMAN|1223333' |
sed 's/[^|]/1+/g;s/|/p/;1i0 1+' |dc
15
con $IFS
...
IFS=\|; set -f; set -- ${0+RAMSITALSKHMAN|1223333}; echo $((${#1}+1))
Eso también le dirá cómo muchos no son como ...
echo $(($#-1))