2010-12-17 14 views
20

Estoy usando BASH, y no sé cómo encontrar una subcadena. Sigue fallando, tengo una cadena (¿debería ser una matriz?)¿Cómo encontrar la subcadena dentro de una cadena (o cómo grep una variable)?

A continuación, LIST es una lista de cadenas de nombres de bases de datos, SOURCE es la respuesta, una de esas bases de datos. A continuación sigue sin funcionar:

echo "******************************************************************" 
echo "*     DB2 Offline Backup Script      *" 
echo "******************************************************************" 
echo "What's the name of of the database you would like to backup?" 
echo "It will be named one in this list:" 
echo "" 
LIST=`db2 list database directory | grep "Database alias" | awk '{print $4}'` 
echo $LIST 
echo "" 
echo "******************************************************************" 
echo -n ">>> " 
read -e SOURCE 

if expr match "$LIST" "$SOURCE"; then 
    echo "match" 
    exit -1 
else 
    echo "no match" 
fi 
exit -1 

También he probado esto, pero no funciona:

if [ `expr match "$LIST" '$SOURCE'` ]; then 
+1

Es difícil responder cualquier tipo de pregunta sin saber qué 'LISTA' y 'FUENTE' parecen – SiegeX

+0

posible duplicado de [Cadena contiene en bash] (http://stackoverflow.com/questions/229551/string-contains- in-bash) – sje397

+0

En Bash, casi siempre no hay razón para usar 'expr' que es una utilidad externa. –

Respuesta

41
LIST="some string with a substring you want to match" 
SOURCE="substring" 
if echo "$LIST" | grep -q "$SOURCE"; then 
    echo "matched"; 
else 
    echo "no match"; 
fi 
+0

: Esto funciona perfectamente para mí .Gracias – Urvashi

+0

2 cuestiones a considerar con este enfoque: (1) grep usa expresiones regulares por lo que algunos caracteres coincidirán inesperadamente o causarán errores; (2) Usar grep (o cualquier cosa que no esté incorporada en bash) genera un proceso separado que se ejecutará más despacio (solo importa en casos de mayor escala). – codesniffer

0

expr se utiliza en lugar de [en lugar de su interior, y las variables son solo se ha expandido dentro de comillas dobles, intente esto:

if expr match "$LIST" "$SOURCE"; then 

Pero no estoy muy seguro de lo que se supone que SOURCE representa.

Parece que su código se leerá en un patrón de la entrada estándar, y saldrá si coincide con un alias de la base de datos, de lo contrario, se repetirá "ok". ¿Es eso lo que quieres?

0

Bueno, ¿qué pasa con algo como esto:

PS3="Select database or <Q> to quit: " 
select DB in db1 db2 db3; do 
    [ "${REPLY^*}" = 'Q' ] && break 
    echo "Should backup $DB..." 
done 
5

Si está utilizando bash puede decir

if grep -q "$SOURCE" <<< "$LIST" ; then 
    ... 
fi 
22

También puede comparar con comodines:

if [[ "$LIST" == *"$SOURCE"* ]]

+6

Siempre debe citar las cadenas, como: 'if [[" $ list "== *" $ source "*]]' – maganap

1

Puede utilizar "índice" si sólo quiere encontrar un solo carácter, por ejemplo:

LIST="server1 server2 server3 server4 server5" 
SOURCE="3" 
if expr index "$LIST" "$SOURCE"; then 
    echo "match" 
    exit -1 
else 
    echo "no match" 
fi 

de salida es:

23 
match 
3

Esto funciona en Bash y sin que se bifurcan comandos externos:

function has_substring() { 
    [[ "$1" != "${2/$1/}" ]] 
} 

Uso del ejemplo:

name="hello/world" 
if has_substring "$name" "/" 
then 
    echo "Indeed, $name contains a slash!" 
fi 
+1

La ventaja de esta solución es que no depende de ningún comando externo ni de los descriptores de archivos (a través de redirección o tuberías). – wrlee

+0

Tenga en cuenta que esto está utilizando una expresión regular para buscar la subcadena (y también reemplaza fuera de lugar), por lo que caracteres especiales en la búsqueda (subcadena) pueden causar resultados inesperados. Pero si la expresión regular está bien, ¿por qué no hacer una búsqueda de expresiones regulares (es decir, no hay necesidad de reemplazarla)? Ejemplo de sintaxis: if [["$ string" = ~ $ substring]] – codesniffer

1
expr match "$LIST" '$SOURCE' 

no funcionan debido a esta función de búsqueda $ FUENTE de principio de la cadena y devolver la posición justo después de patrón $ FUENTE si encontramos otro 0. Por lo que debe escribir otro código:

expr match "$LIST" '.*'"$SOURCE" or expr "$LIST" : '.*'"$SOURCE" 

La expresión $ SOURCE debe estar doblemente citado para que un analizador pueda establecer la sustitución. La única cita no sustituye y el código de arriba buscará la cadena de texto $ SOURCE desde el comienzo de $ LIST. Si necesita el comienzo de la cadena, reste la longitud $ SOURCE, por ejemplo, $ {# SOURCE}. Usted puede escribir también

expr "$LIST" : ".*\($SOURCE\)" 

Esta función simplemente extraer $ FUENTE desde $ LISTA y lo devuelve. Obtendrá cadena vacía else. Pero tienen un problema con doble comilla doble.No sé cómo se resuelve sin usar una variable adicional. Es una solución ligera. Entonces puede escribir en C. Hay una función lista strstr. No utilice el índice expr, por lo que es muy atractivo. Pero la búsqueda de índice no es una subcadena y solo la primera char.

Cuestiones relacionadas