В системе с установленной командой GNU stat (как и в любом стандартном дистрибутиве Linux) вы можете получить тип fs для данного файла, не требуя любой синтаксический анализ с использованием команды stat
:
stat -f -c %T filename
-f
указывает stat
предоставить информацию о файловой системе вместо файла, и -c% T
устанавливает выходной формат, включающий только тип файловой системы, удобочитаемый человеком (% T
).
Таким образом, вы можете использовать это (в bash) как:
if [[ $(stat -f -c %T filename) == ext4 ]]; then
# ext4 specific command
fi
man stat
предоставит дополнительную информацию.
Con algunas mejoras a su secuencia de comandos,
#!/bin/bash
cd "$1" || { printf 'unable to navigate to target\n' >&2; exit 1 ; }
for file in *.dat; do
test -f "$file" || continue
awk 'count+=sub(/<Overall>/, ""){sum+=$0}END{print (count)?(sum/count):0}}' "$file"
done
cd
-ing a "$1"
, no necesita for file in "$1"
, pero simplemente recorra las extensiones de archivo necesariasfor file in *.dat
test -f "$file" || continue
se asegurará de que si no hay archivos en la ruta que se está examinando, se produzca una salida ordenada del bucle for -en lugar de pasar un globo no expandido a awk
para procesar $file
en lugar de una cadena literal file
. Las variables de shell deben tener el prefijo $
antes del nombre y, por lo general, deben estar entre comillas dobles -. END
de awk
para comprobar si el recuento no es -cero antes de dividirlo. for file in "$1"
ejecutará el bucle exactamente una vez, con file
establecido en el valor literal del primer argumento del script. Dado que se cita "$1"
, los comodines dentro no se expanden. Si pasa un directorio al script, también pasará el nombre del directorio a awk
, y es probable que no le guste mucho, mi gawk
dice:
gawk: warning: command line argument `/tmp/test/' is a directory: skipped
Si desea ejecutar el ciclo sobre cada archivo individualmente, use un comodín en el lugar adecuado. El *
aquí se expandirá a los nombres de archivo en el directorio actual, el que se da como argumento ya que acabamos de hacer un cd
allí:
#!/bin/sh
cd "$1" || exit 1
for file in * ; do
awk '...' "$file"
done
Alternativamente, puede pasar una lista de nombres de archivo como argumento al script y luego recorrerlos:
#!/bin/sh
for file in "$@" ; do
awk '...' "$file"
done
En la práctica, haría myscript /some/path/hotel*.dat
y dejaría que el shell expandiera los nombres de los archivos a la línea de comandos de los scripts. "$@"
se expande a la lista de argumentos de línea de comando.
Dicho esto, el guión awk
también está un poco fuera de lugar. Tal como lo escribiste, la condición de la primera regla es count+=sub(/<Overall>/, "")
. Eso es cierto siempre que count
sea distinto de cero después de la suma, independientemente de lo que sub()
devuelva esta vez. Esto significa que la regla {sum+=$0}
se ejecuta cada vez que <Overall>
se ve al menos una vez. Sumará sin aumentar count
.
Probablemente querrás algo como esto:
awk '/^<Overall>/ {sub(/<Overall>/, ""); count += 1; sum += $0} END {print sum/count}' "$file"
Para mostrar el nombre del archivo, puede echo
:
#!/bin/sh
cd "$1" || exit 1
for file in * ; do
printf "%s " "$file"
awk '/^<Overall>/ {sub(/<Overall>/, ""); count += 1; sum += $0} END {print sum/count}' "$file"
done
Con un soloawk
guión (sin for
bucle y múltiples awk
invocaciones):
Archivos de entrada de muestra:
$ head reviews_folder/hotel_*.dat
==> reviews_folder/hotel_111.dat <==
<Overall>1
<Overall>4
<Overall>3
==> reviews_folder/hotel_222.dat <==
<Overall>11
<Overall>5
<Overall>7
==> reviews_folder/hotel_333.dat <==
<Overall>7
<Overall>4
<Overall>10
awk -F'>' 'fn && FILENAME != fn{
sub(".*/", "", fn);
print fn, sprintf("%.2f", sum/n); sum = 0
}
{ sum += $2; n = FNR; fn = FILENAME }
END{
sub(".*/", "", fn);
print fn, sprintf("%.2f", sum/n)
}' reviews_folder/hotel_*.dat
La salida:
hotel_111.dat 2.67
hotel_222.dat 7.67
hotel_333.dat 7.00
Use el siguiente comando contra cada archivo. Obtendrá el promedio. Probado y funcionado bien
Entrada
<Overall>1
<Overall>4
<Overall>3
i=`awk '{print NR}' hotel_111.dat| tail -1 `
awk -F ">" -v i="$i" 'BEGIN{sum=0} {sum=sum+$2} END{print FILENAME;print sum/i}' hotel_111.dat | sed "N;s/\n/ /g"
salida
hotel_111.dat 2.66667