Wie aggregiere ich Daten aus mehreren Dateien in einer Datei?

Wie aggregiere ich Daten aus mehreren Dateien in einer Datei?

Ich habe diese Verzeichnisstruktur für ungefähr 100 Benutzer.

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

Der Inhalt der info.txtDateien sieht folgendermaßen aus.

5 some_other_info

Im Grunde handelt es sich nur um eine Zeile, die eine Zahl, ein Leerzeichen und dann etwas Text (darin können auch Leerzeichen sein) enthält.

Ich möchte eine Datei erstellen result.txt, die so aussieht.

user1 5
user2 6
user3 7
...

Wobei user1, user2, user3, ... dem Verzeichnisnamen entsprechen und die Zahlen mit dem Inhalt der jeweiligen info.txtDateien übereinstimmen.

Sie können davon ausgehen, dass die Namen der Benutzerverzeichnisse keine Leerzeichen enthalten.

Wie kann dies am besten getan werden?

Antwort1

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

Antwort2

Dies können Sie mit einer einfachen Schleife erreichen for.

{
  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

Antwort3

Eine Variation von Stephanes Antwort:

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

Die Verwendung von (GNU) findschützt xargsdavor, dass die Anzahl der Benutzer die maximale Anzahl an Programmargumenten (die systemabhängig ist) überschreitet.

(xargs teilt die Eingabe korrekt auf und ruft bei Bedarf wiederholt awk auf)

Antwort4

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

verwandte Informationen