Linux Fu: Cadenas Bash

Si eres un programador tradicional, usando bash porque un script puede parecer restrictivo a veces, pero para ciertas tareas, bash puede ser muy productivo. Resulta que algunos de los límites de bash realmente hay límites de shells más antiguos y código de personas para que sean compatibles. Otros problemas percibidos se deben a algunas de las características avanzadas en bash son arcanos o confusos.

Las cuerdas son un buen ejemplo. no piensas en bash como un lenguaje de manejo de cadenas, pero tiene muchas formas poderosas de manejar cadenas. De hecho, puede tener demasiadas formas, porque la funcionalidad termina en más de un lugar. Por supuesto, también puede llamar a los programas y, a veces, es más fácil llamar awk o un script de Python para hacer la carga pesada.

Pero quedémonos con bash-ismos para manejar cadenas. Obviamente, puede colocar una cadena en una variable de entorno y retirarla. Supongo que sabes cómo funcionan la interpolación y las comillas de cadenas. En otras palabras, esto debería tener sentido:

echo "Your path is $PATH and the current directory is ${PWD}"

El largo y el corto

Supongamos que desea saber la longitud de una cadena. Esta es una operación de cadena bastante básica. En bashpuedes escribir ${#var} encontrar la longitud de $var:

#/bin/bash
echo -n "Project Name? "
read PNAME
if (( ${#PNAME} > 16 ))
then
   echo Error: Project name longer than 16 characters
else
   echo ${PNAME} it is!
fi

El "(" forma un contexto aritmético, por lo que puede salirse con la suya con un mayor que un signo tácito aquí. Si no le importa usar expr - que es un programa externo - hay al menos dos formas adicionales de llegar allí:

echo ${#STR}
expr length "${STR}"
expr match "${STR}" '.*'

Por supuesto, si te permites llamar fuera de bashpodrías usar awk o algo más para hacer esto también, pero nos quedaremos expr porque es relativamente ligero.

Cuchillo del ejército suizo

De hecho, expr puede hacer muchas manipulaciones de cadenas además de la longitud y la compatibilidad. Puedes tirar de una cuerda de una cuerda usando substr. A menudo es conveniente usar index primero busque un carácter separado en la cadena. La expr El programa usa 1 como el primer carácter de la cadena. Así por ejemplo:

#/bin/bash
echo -n "Full path? "
read FFN
LAST_SLASH=0
SLASH=$( expr index "$FFN" / ) # find first slash
while (( $SLASH != 0 ))
do
   let LAST_SLASH=$LAST_SLASH+$SLASH  # point at next slash
   SLASH=$(expr index "${FFN:$LAST_SLASH}" / )  # look for another
done
# now LAST_SLASH points to last slash
echo -n "Directory: "
expr substr "$FFN" 1 $LAST_SLASH
echo -or-
echo ${FFN:0:$LAST_SLASH}
# Yes, I know about dirname but this is an example

Introduzca la ruta completa (como /foo/bar/la-tecnologia) y el script encontrará la última barra inclinada e imprimirá el nombre hasta la última barra inclinada inclusive usando dos métodos diferentes. Este guión se utiliza expr pero también usa la sintaxis para bash'es una extracción de subcadena incorporada que comienza en el índice cero. Por ejemplo, si la variable FOO contiene "La-Tecnologia":

  • $ {FOO} -> La-Tecnologia
  • $ {FOO: 1} -> día de pago
  • $ {FOO: 5: 3} -> día
  • El primer número se compensa y el segundo es la longitud si es positivo. También puede hacer que cualquiera de los números sea negativo, aunque necesita un espacio después de los dos puntos si el desplazamiento es negativo. El último carácter de la cadena está en el índice -1, por ejemplo. La longitud negativa es una forma abreviada de una posición absoluta del final de la cadena. Hacer:

    • $ {FOO: -3} -> día
    • $ {FOO: 1: -4} -> acuse de recibo
    • $ {FOO: -8: -4} -> Hackear
    • Por supuesto, cualquiera de los dos números podría ser variable, como puede ver en el ejemplo.

      Menos es más

      A veces no quieres encontrar algo, solo quieres deshacerte de él. bash tiene muchas formas de eliminar subcadenas con cadenas fijas o coincidencia de patrones basados ​​en globo. Hay cuatro variaciones. Un par de eliminaciones elimina las subcadenas más largas y más cortas posibles del frente de la cadena y el otro par hace lo mismo desde la parte posterior de la cadena. Considera esto:

TSTR=my.first.file.txt
echo ${TSTR%.*} # prints my.first.file
echo ${TSTR%%.*}  # prints my
echo ${TSTR#*fi}  # prints rst.file.txt
echo $TSTR##*fi} # prints le.txt

Transformación

Por supuesto, a veces no desea eliminar tanto como desea reemplazar una cadena con otra cadena. Puede usar una sola barra para reemplazar la primera aparición de una cadena de búsqueda o dos barras para reemplazar en todo el mundo. También es posible que no proporcione un cable de reemplazo y se le dará otra forma de quitar partes del cable. Otro truco es agregar # o% para anclar la coincidencia al principio o al final de la cadena, como con la eliminación.

TSTR=my.first.file.txt
echo ${TSTR/fi/Fi}   # my.First.file.txt
echo ${TSTR//fi/Fi}  # my.First.File.txt
echo ${TSTR/#*./PREFIX-} # PREFIX-txt  (note: always longest match)
echo ${TSTR/%.*/.backup}  # my.backup (note: always longest match)

Varios

Algunas de las formas más comunes de manejar cuerdas bash se refiere al tratamiento de los parámetros. Suponga que tiene un script esperando una variable llamada OTERM para ser configurado pero quiere estar seguro:

REALTERM=${OTERM:-vt100}

Ahora REALTERM tendrá el valor de OTERM o la cadena "vt100" si no hubiera nada en ella OTERM. A veces quieres configurar OTERM en sí mismo, por lo que si bien podría asignar a OTERM en lugar de REALTERM, Hay una manera más fácil. Use: = en lugar de: - secuencia. Si hace esto, no necesita ninguna tarea, aunque puede usar una si lo desea:

echo ${OTERM:=vt100}  # now OTERM is vt100 if it was empty before

También puede invertir el significado para reemplazar el valor solo si el valor principal no está vacío, aunque esto generalmente no es tan útil:

echo ${DEBUG:+"Debug mode is ON"}  # reverse -; no assignment

Una medida más drástica le permite imprimir un mensaje de error en stderr y detener un shell no interactivo:

REALTERM=${OTERM:?"Error. Please set OTERM before calling this script"}

De todos modos

Convertir mayúsculas o minúsculas es bastante sencillo. Puede proporcionar un patrón de globo que coincida con un solo carácter. Si lo omite, es lo mismo que ?, que coincide con cualquier carácter. Puede optar por cambiar todos los caracteres coincidentes o simplemente intentar hacer coincidir el primer carácter. Aquí están los ejemplos requeridos:

NAME="joe La-Tecnologia"

echo ${NAME^} # prints Joe La-Tecnologia (first match of any character)
echo ${NAME^^} # prints JOE la-tecnologia.com (all of any character)
echo ${NAME^^[a]} # prints joe la-tecnologia.com (all a characters)
echo ${NAME,,] # prints joe la-tecnologia (all characters)
echo ${NAME,] # prints joe La-Tecnologia (first character matched and didn't convert)
NAME="Joe La-Tecnologia"
echo ${NAME,,[A-H]} # prints Joe la-tecnologia (apply pattern to all characters and convert A-H to lowercase)

Últimas versiones de bash también puede convertir mayúsculas y minúsculas usando ${[email protected]} y ${[email protected]} junto con solo el primer carácter usando @u y @lpero tu kilometraje puede variar.

Aprobar el examen

Probablemente haya notado que cuando realiza una prueba estándar, en realidad se llama programa:

if [ $f -eq 0 ]
then ...

Si haces ls en /usr/binverás lo que en realidad se puede llamar "[” used as a shorthand for the test program. However, bash has its own test in the form of two brackets:

if [[ $f == 0 ]
entonces ...

Esta prueba integrada puede manejar expresiones regulares usando = ~, por lo que esta es otra opción para hacer coincidir cadenas:

if [[ "$NAME" =~ [hH]a.k ]] ...

Elegir sabiamente

Por supuesto, si procesa mucho texto, es posible que no necesite usarlo bash. Incluso si lo eres, no olvides que siempre puedes usar otros programas como tr, awk, sed, y muchos otros para hacer tales cosas. Claro, actuar no será tan bueno, probablemente, pero si te importa actuar, ¿por qué escribir un guión?

A menos que estés maldiciendo por completo un guión, es bueno tener algunos de estos trucos en tu bolsillo trasero. Úselos sabiamente.

Gloria Vega
Gloria Vega

Deja una respuesta

Tu dirección de correo electrónico no será publicada.