wc -c не работает в цикле в скрипте [дубликат]

-2
17.06.2018, 00:10
1 ответ

El problema es que su código está haciendo cd..antes de terminar con todos los archivos en un directorio. En general, no es necesario cdentrar en los directorios para obtener los nombres de los archivos, y puede ser confuso ir y venir de los directorios en bucles. También puede generar problemas extraños si está redirigiendo la salida a nombres de archivo con rutas relativas, etc. dentro de los bucles. En este script, tampoco sabría dónde(en qué directorio )se encontró el archivo, porque siempre busca en el directorio actual.

Solucionado esto al no usar cd, y también al no usar ls, lo que permite que el script funcione con nombres de archivo que tienen espacios y otros caracteres inusuales:

#!/bin/sh

find_smaller () {
    dir=$1
    size=$2

    for pathname in "$dir"/*; do
        if [ -f "$pathname" ]; then
            # this is a regular file (or a symbolic link to one), test its size
            filesize=$( wc -c <"$pathname" )
            if [ "$filesize" -lt "$size" ]; then
                printf 'Found %s, size is %d\n' "$pathname" "$filesize"
            fi
        elif [ -d "$pathname" ]; then
            # this is a directory (or a symbolic link to one), recurse
            printf 'Entering %s\n' "$pathname"
            find_smaller "$pathname" "$size"
        fi
    done
}

find_smaller "$@"

En el código anterior, $pathnameserá no solo el nombre del archivo o directorio actual que estamos viendo, sino también su ruta relativa al directorio de inicio.

Nótese también la cita de todas las expansiones variables. Sin citar la variable $pathname, por ejemplo, invocaría el nombre de archivo globbing si un nombre de archivo contiene caracteres como *o ?.

Véase también:


Usando bashy su opción de shell globstar. Con esta opción configurada, el patrón global **coincide con todos los nombres de ruta debajo del directorio dado. Esto significa que no tenemos que recorrer explícitamente la estructura de directorios en nuestro script:

#!/bin/bash

dir="$1"
size="$2"

shopt -s globstar

for pathname in "$dir"/**; do
    [ ! -f "$pathname" ] && continue

    filesize=$( wc -c <"$pathname" )

    if [ "$filesize" -lt "$size" ]; then
        printf 'Found %s, size is %d\n' "$pathname" "$filesize"
    fi
done

En lugar de escribir su propio árbol de directorios, puede usar find. El siguiente comando findhace lo que tu código intenta hacer:

find /home/161161 -type f -size -100c

Como guión:

#!/bin/sh
dir=$1
size=$2
find "$dir" -type f -size -"$size"c

La única pequeña diferencia entre el caminante de directorio explícito y la variación findes quefind(cuando se usa como se indicó anteriormente )ignorará los enlaces simbólicos, mientras que la función de shell anterior resolverá los enlaces simbólicos, lo que posiblemente cause bucles de directorio para ser atravesado infinitamente, o los mismos datos para ser contados más de una vez.

Usando find, el contenido de los archivos no se leerá para determinar el tamaño del archivo. En su lugar, se realizará una llamada a la biblioteca lstat()para consultar el tamaño del archivo en el sistema de archivos. ¡Esto es muchas veces más rápido que usar wc -c!

En la mayoría (pero no en todos )Unices, también puede usar la utilidad de línea de comandos statpara obtener el tamaño del archivo. Consulte el manual de esta utilidad en su sistema para saber cómo usarla (. Funciona de manera diferente en Linux y BSD ).

3
28.01.2020, 05:15

Теги

Похожие вопросы