¿Cómo agrego datos de muchos archivos en un solo archivo?

¿Cómo agrego datos de muchos archivos en un solo archivo?

Tengo esta estructura de directorios para unos 100 usuarios.

users
- user1
  - info.txt
- user2
  - info.txt
- user3
  - info.txt
...

Dentro de los info.txtarchivos, el contenido se ve así.

5 some_other_info

Básicamente, es solo una línea que contiene un número, un espacio y luego algo de texto (puede tener espacios dentro).

Me gustaría crear un archivo result.txtque se parezca a este.

user1 5
user2 6
user3 7
...

Donde user1, user2, user3, ... coincide con el nombre del directorio y los números coinciden con lo que hay en sus respectivos info.txtarchivos.

Puede suponer que los directorios de usuarios no tienen espacios en sus nombres.

¿Cuál es una buena manera de hacer esto?

Respuesta1

awk '{split(FILENAME,u,"/"); print u[2], $1}' users/*/info.txt

Respuesta2

Puedes hacer esto con un forbucle simple.

{
  for userd in users/*/; do 
    if [[ -e "$userd/info.txt" ]]; then
      read num _ < "$userd/info.txt"
      printf '%s %s\n' "$user" "$num"
    fi
  done
} > out.txt

Respuesta3

Una variación de la respuesta de Stéphane:

$ cd users && \
      find -mindepth 2 -maxdepth 2 -type f -name info.txt  \
    | xargs awk '{ split(FILENAME,u,"/"); print u[2], $1 }'

El uso de (GNU) findy xargsprotege contra el número de usuarios que exceden el número máximo de argumentos del programa (que depende del sistema).

(xargs dividirá correctamente la entrada y llamará repetidamente a awk si es necesario)

Respuesta4

for f in users/*/info.txt; do
    set -- $(< $f)
    num=$1

    # choose one of:
    user=$(basename $(dirname $f))
    # or
    dir=${f%/*}; user=${dir##*/}

    echo $user $num
done

información relacionada