2009-11-30 16 views
5
#!/bin/bash 

for ((var=0; var<20; var++)) 
do 
echo " Number is: $(grep 'Multiple_Frame = echo **$var**' 20mrf.txt | wc -l)" >>statisic.txt 

done 

Este programa de shell no puede producir el resultado correcto que tal vez el motivo de la variable incorrecta vuelva en el segundo comando grep.cómo grep una variable en el programa de shell?

¿Cómo puedo grep una variable dentro de la segunda oración de eco? para grep diferentes cosas de acuerdo con el cambio var?

¡Muchas gracias!

Respuesta

4

Como han dicho otros, el problema es que las comillas simples impiden la expansión de la variable. Sin embargo, el uso de $() le permite utilizar comillas dobles:

echo " Number is: $(grep "Multiple_Frame = echo **$var**" 20mrf.txt | wc -l)" >>statisic.txt 

aunque sospecho que algo como esto es lo que quería decir:

echo " Number is: $(grep "Multiple_Frame = $var" 20mrf.txt | wc -l)" >>statisic.txt 

También debe tener en cuenta que grep tiene una opción para dar salida al contar por lo que se puede omitir wc:

echo " Number is: $(grep -c "Multiple_Frame = $var" 20mrf.txt)" >>statisic.txt 
1

Debe almacenar cada sustitución en una variable. De esta manera:

#!/bin/bash 

for ((var=0; var < 20; var++)) 
do 

count=`grep "Multiple_Frame = $var" 20mrf.txt | wc -l` 
echo " Number is: $count" >> statisic.txt 

done
+0

después de dividir el comando como lo que me dijo, obtengo la siguiente información de error. ./loop_count_reference_frame_no.sh: línea 10: grep "Multiple_Frame = $ var" 20mrf.txt | wc -l: comando no encontrado – MaiTiano

+0

tal vez la comilla simple no puede generar el resultado de grep correcto y enviarlo a la nueva variable de "conteo". – MaiTiano

+0

Sé cuál es el lugar equivocado ... Debería usar esc no simple comilla simple. Gracias de cualquier manera. – MaiTiano

0

la cadena dentro de $ (...) es citado con comillas simples ('...') esta citando evita que la variable de expansión. Use comillas dobles en su lugar. En su caso:

#!/bin/bash 

for ((var=0; var<20; var++)) 
do 
echo " Number is: $(grep 'Multiple_Frame = echo **'"$var"'**' 20mrf.txt | wc -l)" >>statisic.txt 

done 

Tenga en cuenta que en este ejemplo, parece que las comillas dobles para el comando echo ya están abiertas, pero debe tener en cuenta que el $(...) se evalúa en primer lugar, y no hay comillas dobles dentro de él . Así que el cambio aquí es cerrar la comilla simple de la comilla doble abierta grep en su lugar, y cerrar las comillas dobles y volver a abrir la comilla simple más adelante.

Esta larga explicación ilustra el beneficio de separar la expresión, como sugieren otras respuestas.

+0

cerrar la comilla simple de grep no puede ayudar a producir un resultado correcto. de todos modos, gracias ~ – MaiTiano

1

Ok, el segundo problema [sic] es con su cita en la línea 5. La referencia a $ var nunca se expandirá porque está contenida entre comillas simples. Puede solucionarlo reemplazando las comillas simples (') con comillas dobles escapadas (\").

El primer problema [sic] es que está tratando de hacer demasiado en una sola línea, lo que provoca un problema de anidación con comillas. Divida la línea en múltiples comandos, almacenando los resultados intermedios según sea necesario. Sí, podría funcionar un poco más lento, pero ahorrará MUCHO tiempo depurándolo y manteniéndolo.

Segunda ley de Trader: si tiene que elegir entre optimizar el rendimiento y optimizar el mantenimiento, SIEMPRE elija hacer que su código sea más fácil de mantener. Las computadoras se vuelven más rápidas todo el tiempo; Los programadores no.

2

@OP, hacer lo que hace que w ay es bastante ineficiente. Estás llamando grep y wc 20 veces en el mismo archivo. Abra el archivo una sola vez y obtenga todas las cosas que desee en 1 iteración del contenido del archivo. Ejemplo en bash 4.0

declare -A arr 
while read -r line 
do 
    case "$line" in 
     *"Multiple_Frame ="*) 
      line=${line#*Multiple_Frame = } 
      num=${line%% *} 
      if [ -z ${number_num[$num]} ] ;then 
       number_num[$num]=1 
      else 
       number_num[$num]=$((number_num[$num]+1)) 
      fi 
      ;; 
    esac  
done <"file" 
for i in "${!number_num[@]}" 
do 
    echo "Multiple_Frame = $i has ${number_num[$i]} counts" 
done 

Del mismo modo, puede utilizar matrices asociativas en gawk para ayudarlo a realizar esta tarea.

gawk '/Multiple_Frame =/{ 
    sub(/.*Multiple_Frame = /,"") 
    sub(/ .*/,"") 
    arr["Multiple_Frame = "$0]=arr["Multiple_Frame = "$0]+1 
}END{ 
    for(i in arr) print i,arr[i] 
}' file 
+0

OMG, su programa es increíble. Como soy un novato en la programación de Linux, realmente me estás dando una buena lección. Gracias. ~ – MaiTiano

Cuestiones relacionadas