Para responder específicamente a sus preguntas:
Q1. la expresión $x | wc -l
significa "ejecutar el comando $x
y canalizar los resultados a wc -l
". Para canalizar el contenidos de $x
a wc
, podría utilizar num=`echo "$x" | wc -l`
o (usando un bash aquí la cadena ) num=`wc -l <<< "$x"`
.
Sin embargo, la forma "backtick" de sustitución de comandos está obsoleta - es mejor acostumbrarse a utilizar $( ... )
es decir
num=$(wc -l <<< "$x")
Tenga en cuenta que esto dará un recuento erróneo si algún nombre de archivo contiene caracteres de nueva línea (lo cual está permitido en Linux).
Q2. En find . -name '*.$1'
las comillas simples (también conocidas como "comillas duras") alrededor de '*.$1'
impedirá la expansión de $1
así que find
buscará los nombres de archivo que terminen literalmente en $1
. Para permitir la expansión de $1
al tiempo que se evita la expansión prematura de *.
Utiliza las comillas dobles (también conocidas como "comillas blandas"), es decir "*.$1"
Probablemente querrá limitar la búsqueda al directorio de nivel superior en lugar de descender a los subdirectorios (de lo contrario, los resultados serán incoherentes con el recuento obtenido de wc
):
find . -maxdepth 1 -name "*.$1"
Sin embargo, Así es como yo lo haría, suponiendo que un bash
Shell:
report() {
shopt -s nullglob
local ext="$1"
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf '\t%s\n' "$@"
fi
}
Esto evita Bash Pitfall #1 (analizando la salida de ls
en lugar de utilizar un glob de Shell) y utiliza el Shell de set
para leer los nombres de los archivos que coinciden en el $@
matriz de parámetros posicionales. De esta manera, se puede utilizar $#
para contar el número de archivos de forma inequívoca (incluso si contienen nuevas líneas - donde la tubería ls
a wc
daría un recuento erróneo), y no hay necesidad de utilizar un find
para obtener de nuevo los nombres coincidentes.
Si quieres mostrar los nombres de los archivos sin la extensión, puede reemplazar $@
en el printf
con ${@%.*}
que elimina la subcadena final más corta que coincida con .*
de cada elemento de la matriz utilizando expansión de parámetros .
Aunque he optado por utilizar un (( ... ))
para comprobar el número de archivos, no hay nada de malo en utilizar la construcción aritmética POSIX [ $# -le 10 ]
o [ $# -lt 10 ]
si lo prefiere. El extra $# > 0
es sólo para mantener la salida bonita cuando no hay archivos de la extensión dada.
Se puede ampliar fácilmente la función para que acepte varias extensiones utilizando una matriz para las extensiones:
function report {
shopt -s nullglob
local exts=( "$@" )
for ext in "${exts[@]}"; do
set -- *."$ext"
printf 'There are %d %s files' $# "$ext"
if (( $# > 0 && $# < 10 )); then
printf ': \n'
printf '\t%s\n' "$@"
else
printf '.\n'
fi
done
}
Ejemplo de uso:
$ report txt jpg foo
There are 71 txt files.
There are 4 jpg files:
b.jpg
foo.jpg
inv_logpolar.jpg
logpolar.jpg
There are 0 foo files.