INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Quería ejecutar el segundo comando ( head -1) solo si el primer comando es exitoso. ¿Cómo mejoro este comando?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Quería ejecutar el segundo comando ( head -1) solo si el primer comando es exitoso. ¿Cómo mejoro este comando?
Respuestas:
Prueba esto:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Al pasar xargsel -rindicador, solo se ejecutará basenamesi lee al menos un elemento de la entrada estándar ( head -1).
head -1 se ejecutará pero no verá ni capturará ningún resultado.
Además, si no desea que el usuario vea ningún resultado de error ls, puede redirigir lsla secuencia stderr de /dev/null.
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
También tenga en cuenta que agregué comillas alrededor $MY_DIR. De esa manera, el comando no fallará si $MY_DIRcontiene espacios.
Si está utilizando un shell moderno como bash, debe usar un $( )shell de captura en lugar de backticks. También debe considerar cambiar el estilo de sus variables. En general, debe evitar el uso de nombres de variables en mayúsculas en los scripts. Ese estilo está generalmente reservado para variables reservadas y ambientales.
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basenamefunciona.
En una tubería, todos los comandos se inician y se ejecutan simultáneamente, no uno tras otro. Por lo tanto, debe almacenar la salida en algún lugar.
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
Tenga en cuenta que se supone que los nombres de archivo no contienen caracteres de nueva línea. El uso xargstambién significaría problemas con caracteres en blanco, comillas simples y dobles y barras invertidas. Dejar variables sin comillas significaría problemas con el espacio, la tabulación y los caracteres comodín. Olvidar --significaría problemas con los nombres de archivo que comienzan con -.
Para obtener el nombre base del archivo más antiguo zshsin ninguna de esas restricciones en los caracteres (también evita el problema del tamaño limitado de los argumentos de un comando):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Si no hay coincidencia, ese comando fallará y abortará el script. También puedes hacer:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
En cuyo caso, la first_file_namematriz contendrá 1 elemento si hay una coincidencia o 0 si no. Entonces puedes hacer:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Encuentre el último archivo modificado en un directorio:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
Uso: latest [directory/path/ [.extension]]
En lugar de llamar a basename, use la expansión de parámetros.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
En un directorio con estos contenidos:
foo.xml bar.xml baz.xml newest.xml
El contenido de la variable base_fn sería: newest
Para usar esto correctamente para cumplir con el propósito de su solicitud:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
EDITAR: al revisar la pregunta, me di cuenta de que el lscomando en cuestión está buscando el archivo más antiguo en un directorio. esta misma función podría renombrarse oldesty tener [[ $file -ot $oldest ]] && oldest=$fileque lograr el mismo efecto. disculpas por cualquier confusión.
Lo importante a tener en cuenta es que absolutamente, bajo ninguna circunstancia en la humanidad, no debe analizar la salida de ls. Nunca.
lsenfoques basados en, si hay enlaces simbólicos, se considerará el tiempo de modificación del objetivo de los enlaces simbólicos (agregue la -Lopción lspara obtener el mismo comportamiento allí).
Creo que la mejor opción aquí es:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
si no hay archivo, el código de retorno de ls es 2 pero si encuentra algún archivo será 0.
lsNo fallará.