Pregunta Lectura de entrada de usuario en Linux


He escrito una secuencia de comandos para los archivos de la lista en función del mes que el usuario lee de la siguiente manera:

echo "Enter Month"
read month
ls -al | awk '$6 == "$month" {print}'

Y estoy dando la entrada del usuario como Aug, no estoy obteniendo ningún resultado. Pero cuando estoy escribiendo

ls -al | awk '$6 == "Aug" {print}'

Estoy obteniendo el resultado exacto. ¿Estoy haciendo algo mal? Por favor ayuda


2


origen


MacOS (etiqueta) no es Linux (título). - Kamil Maciorowski


Respuestas:


Lo principal es que los nombres de variables no se expanden dentro de comillas simples. Esta es una línea "mejor" (es decir, un poco menos incorrecta):

ls -al              | awk '$6 == "'"$month"'" {print}'
# this is in single quotes ^^^^^^^          ^^^^^^^^^

Pero:

  1. Aún así, esto puede fallar en algunos lugares. Conjunto LC_ALL=C antemano o tal vez tal vez.
  2. Con $month puedes inyectar (¿casi?) algo en awk. Hay mejores formas de usar variables dentro awk; -v opción debería ser mucho más seguro (gracias user000001 por señalar esto).
  3. No debe analizar la salida de ls en primer lugar.

La solución correcta podría usar find y stat. El siguiente código puede no ser la solución más rápida, pero es más robusto debido a:

  • descartando $month valores que no coinciden con los predefinidos,
  • utilizando find en lugar de analizar ls.

El código:

#!/bin/sh
echo "Enter Month"
read month
case "$month" in
  1|01|Jan|jan|January|january)   monthN=01;;
  2|02|Feb|feb|February|february) monthN=02;;
# ...
  10|Oct|oct|October|october)     monthN=10;;
# ...
  *) echo Error! >&2; exit 1;;
esac
find ./ -maxdepth 1 -exec sh -c '[ `stat -c %y "$1" | cut -c 6-7` = "$2" ]' sh {} "$monthN" \; -ls

Probé esto en Debian; puede que no sea súper portátil. Sin embargo, muestra el enfoque general.

La última línea invoca un shell separado para cada objeto en el directorio actual (incluido ./ sí mismo). Este shell usa stat para obtener información de tiempo, luego cut extrae un número de mes de dos dígitos de él. [ ... ] compara el resultado con el número del mes elegido. Si esta prueba tiene éxito entonces find realiza su propio ls en el objeto (puede usar -print o -print0 en lugar).

Tenga en cuenta que esto nunca regresa ../. Por otra parte find le permite usar pruebas adicionales (como -type f), por lo que este enfoque es muy flexible.


8



Agregue otro elemento en la lista de fragmentación: utiliza la interpolación de cadenas para pasar variables a awk, en lugar de usar el -v opción, que es mucho más seguro. - user000001
@ user000001 Gracias. Hecho. - Kamil Maciorowski