Tengo esta estructura de directorios para unos 100 usuarios.
users
- user1
- info.txt
- user2
- info.txt
- user3
- info.txt
...
Dentro de los info.txt
archivos, 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.txt
que 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.txt
archivos.
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 for
bucle 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) find
y xargs
protege 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