Me gustaría eliminar el último carácter de una cadena, probé este pequeño script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
pero imprime "lkj", ¿qué estoy haciendo mal?
fuente
Me gustaría eliminar el último carácter de una cadena, probé este pequeño script:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
pero imprime "lkj", ¿qué estoy haciendo mal?
En un shell POSIX, la sintaxis ${t:-2}
significa algo diferente: se expande al valor de t
si t
está establecido y no es nulo, y de lo contrario al valor 2
. Para recortar un solo carácter por expansión de parámetros, la sintaxis que probablemente desee es${t%?}
Tenga en cuenta que en ksh93
, bash
o zsh
, ${t:(-2)}
o ${t: -2}
(tenga en cuenta el espacio) son legales como una expansión de subcadena, pero probablemente no sean lo que desea, ya que devuelven la subcadena que comienza en una posición a 2 caracteres del final (es decir, elimina el primer carácter i
de la cadena). cadena ijk
).
Consulte la sección de Expansión de parámetros de Shell del Manual de referencia de Bash para obtener más información:
${parameter%word}
elimina el menor coincidencia de patrones sufijoword
- ver la sección de expansión de parámetros deman bash
Con
bash
4.2 y superior, puedes hacer:Ejemplo:
Tenga en cuenta que para versiones anteriores
bash
(por ejemplo,bash 3.2.5
en OS X), debe dejar espacios entre y después de los dos puntos:fuente
bash
versión 4.2-alpha y superior, lástima que la versión a la que tengo acceso sea anterior. : - /${var:offset:lenght}
se agregó solo enbash 4.2
. Quizás OSX agregue su propio parche parabash
.para eliminar los últimos
n
caracteres de una línea que no utilizased
ORawk
:así, por ejemplo, puede eliminar el último carácter
one character
usando esto:de la página de
rev
manual:ACTUALIZAR:
Si no conoce la longitud de la cadena, intente:
fuente
Usar sed debería ser tan rápido como
Tu único eco es entonces
echo ljk | sed 's/.$//'
.Con esto, la cadena de 1 línea podría ser de cualquier tamaño.
fuente
Algunas opciones dependiendo del shell:
t=${t%?}
t=`expr " $t" : ' \(.*\).'`
t=${t[1,-2]}
t=${t:0:-1}
t=${t:0:${#t}-1}
t=${t/%?}
t=${t/~(E).$/}
@ {t=$1} ~~ $t *?
Tenga en cuenta que si bien se supone que todos eliminan el último carácter , encontrará que algunas implementaciones (aquellas que no admiten caracteres de varios bytes) eliminan el último byte (por lo que probablemente corrompería el último carácter si fuera de varios bytes) )
La
expr
variante supone$t
que no termina en más de un personaje de nueva línea. También devolverá un estado de salida distinto de cero si la cadena resultante termina siendo0
(000
o incluso-0
con algunas implementaciones). También podría dar resultados inesperados si la cadena contiene caracteres no válidos.fuente
t=${t%?}
no es Bourne, pero no es probable que encuentres un shell Bourne hoy en día.${t%?}
funciona en todos los demás sin embargo.fish
es trabajo en progreso. 2.3.0, que introdujo elstring
builtin no se lanzó en el momento de las preguntas y respuestas. Con la versión en la que lo estoy probando, necesitastring replace -r '(?s).\z' '' -- $t
(y esperaría que quisieran cambiar eso, deberían cambiar las banderas que pasan a PCRE) o más complicadas. También trata mal con los personajes de nueva línea, y sé que también están planeando cambiar eso.La respuesta más portátil y más corta es casi seguro:
${t%?}
Esto funciona en bash, sh, ash, dash, busybox / ash, zsh, ksh, etc.
Funciona utilizando la expansión de parámetros de shell de la vieja escuela. Específicamente,
%
especifica que se elimine el sufijo de parámetro de coincidencia más pequeñot
que coincida con el patrón global?
(es decir, cualquier carácter).Consulte "Eliminar el patrón de sufijo más pequeño" aquí para obtener una explicación (mucho) más detallada y más antecedentes. Consulte también los documentos de su shell (por ejemplo:)
man bash
en "expansión de parámetros".Como nota al margen, si en su lugar desea eliminar el primer carácter, lo usaría
${t#?}
, ya que las#
coincidencias desde el frente de la cadena (prefijo) en lugar de la parte posterior (sufijo).También vale la pena señalar que ambos
%
y#
have%%
y##
versiones, que coinciden con la versión más larga del patrón dado en lugar de la más corta. Tanto${t%%?}
y${t##?}
haría lo mismo como su único operador en este caso, sin embargo (así que no añadir el carácter adicional inútil). Esto se debe a que el?
patrón dado solo coincide con un solo carácter. Mezclar*
con algunos no comodines y las cosas se vuelven más interesantes con%%
y##
.Comprender las expansiones de parámetros, o al menos conocer su existencia y saber cómo buscarlos, es increíblemente útil para escribir y descifrar scripts de shell de muchos sabores. Las expansiones de parámetros a menudo parecen vudú de caparazón arcano para muchas personas porque ... bueno ... son vudú de caparazón arcano (aunque bastante bien documentado si sabe buscar "expansión de parámetro"). Sin embargo, definitivamente es bueno tenerlo en el cinturón de herramientas cuando estás atrapado en un caparazón.
fuente
Obtiene una subcadena de 0 a la longitud de la cadena -1. Sin embargo, tenga en cuenta que esta resta es específica de bash y no funcionará en otros shells.
Por ejemplo,
dash
no puede analizar inclusoPor ejemplo, en Ubuntu,
/bin/sh
esdash
fuente
También puede usar
head
para imprimir todo menos el último carácter.Pero desafortunadamente algunas versiones de
head
no incluyen la-
opción principal . Este es el caso de lohead
que viene con OS X.fuente
Es bastante fácil hacerlo usando expresiones regulares:
fuente
Algunos refinamientos. Para eliminar más de un carácter, puede agregar varios signos de interrogación. Por ejemplo, para eliminar los dos últimos caracteres de la variable:,
$SRC_IP_MSG
puede usar:fuente
Solo para completar algunos usos posibles de bash puro:
La primera sintaxis toma una subcadena de una cadena, la sintaxis es Para la segunda, observe el signo, que significa 'desde el final de la línea' y la sintaxis es
${STRING:OFFSET:LENGTH}
%
${STRING/PATTERN/SUBSTITUTION}
Y aquí hay dos formas más cortas de lo mencionado anteriormente
Aquí observe nuevamente el
%
signo, que significa 'Eliminar (es decir, reemplazar con' ') el patrón coincidente más corto (aquí representado por el espacio escapado ' \ ' desde el final del PARÁMETRO , aquí llamado STRfuente
Como también podemos usar php en la línea de comandos o scripts de shell. A veces es útil para el análisis quirúrgico.
Con tubería:
fuente
En ksh:
fuente