Tengo una cadena que es el resultado de alguna operación sobre la que no tengo control. Cuando imprimo esta variable usando echo
, obtengo:
echo $myvar
hello
Sin embargo, cuando lo hago
if [ $myvar = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
Siempre entiendo que no son iguales. Sospecho que esto se debe a un newline
personaje.
La cadena también se comporta de manera extraña. Cuando lo hago:
newVAR="this is my var twice: "$myvar$myvar
echo $newVAR
Yo obtengo:
hellois my var twice: hello
¿Cómo puedo verificar si esto se debe realmente a una newline
y, de ser así, eliminarlo?
printf '%q\n' "$string"
obtener una versión escapada de cualquier cadena. Por ejemplo:printf '%q\n' 'foo\n'
->foo\\n
;printf '%q\n' $'foo\n'
->$'foo\n'
echo $foo
. Hazlo en suecho "$foo"
lugar.Respuestas:
El problema es que tiene un retorno de carro incorporado (CR, por sus
\r
siglas en inglés). Esto hace que el punto de inserción de texto del terminal regrese al inicio de la línea que está imprimiendo. Es por eso que está viendo el 'hola' al comienzo de la línea en su$newVAR
ejemplo:sed -n l
muestra una vista legible de caracteres no imprimibles (y al final de la línea).Puede probarlo con una simple verificación de condición de bash:
Puede combinar la prueba y la reparación en un solo paso probando
\r
(s) y eliminándolas mediante:La solución utiliza la expansión de parámetros de Shell . La forma particular utilizada anteriormente es para reemplazar las subcadenas basadas en su patrón proporcionado:
${parameter/pattern/string}
<- Esto reemplaza solo el primer patrón encontrado con una cadena en la variable llamada parámetro *. Para reemplazar todos los patrones, solo necesita cambiar el primero/
a//
.fuente
fix="....
linea?fix
puede servar
en sí - o, a menudo sólo puede utilizar la expansión de parámetros tal cual, sin la necesidad de reasignar el (posiblemente) el valor modificado ..Puedes representar
\r
como$'\r'
en bash:O corta el último
\r
enmyvar
:fuente
Curiosamente, en muchos shells
getopts
es un candidato muy probable para un trabajo como este. Esto puede parecer contradictorio al principio, pero si considera quegetopts
'la función principal es reconocer y ofrecer para la interpretación tantas opciones de línea de comandos de un solo carácter especificadas como se pueden encontrar en una serie concatenada de las mismas, podría comenzar a hacer un poco mas sentido.Para demostrar, desde un
bash
shell:De esa manera, a veces puede ser conveniente permitir
getopts
manejar el desmontaje como una especie de piloto automático de shell para casos como este. Cuando lo haga, puede eliminar los bytes no deseados w / acase
o[
probar]
y crear una copia de seguridad de su cadena desde el byte 1:Dado este simple caso de ejemplo, y dado un shell que admite las expansiones de parámetros ya mencionadas en otra parte, dichas expansiones probablemente le servirán mejor aquí. Pero pensé
getopts
que valdría la pena mencionarlo también en caso de que no conocieras sus capacidades a este respecto. Ciertamente, cuando me enteré, encontré muchas aplicaciones útiles para ello, de todos modos.fuente
Si bien Bash y otros lenguajes de shell son útiles, a veces es mejor usar un lenguaje de script verdadero, como Perl. Perl puede reemplazar scripts de shell que llaman a otros lenguajes como sed y awk, así como comandos UNIX con bastante facilidad. Aprendí esto hace más de 20 años cuando escribía scripts de C-Shell que a su vez llamaban sed, awk y varios comandos UNIX, antes de llamar al código FORTRAN. En Perl haría:
fuente