Wie kann man stdout aufteilen, um auf mehrere Ausgabedateien zuzugreifen?


12

Angenommen, ich habe einen Befehl, commandder eine große Anzahl von Zeilen an stdout ausgibt:

line1
line2
.....
lineN

Ich möchte die Ausgabe auf der Festplatte speichern, aber nicht als einzelne Datei, sondern als eine Folge von Dateien mit jeweils 1000 Zeilen stdout:

file0001.txt:
-------------
line1
....
line1000

file0002.txt:
-------------
line1001
....
line2000

etc

Ich habe versucht, die Antwort zu googeln, aber jedes Mal, wenn Google mich auf teeBefehl verweist , ist dies in dieser Situation nutzlos. Wahrscheinlich gebe ich falsche Abfragen ein.

Antworten:


24

Sobald Sie mit dem Speichern der Datei fertig sind, können Sie splitdie Datei basierend auf der Anzahl der Zeilen immer in Dateiteile oder mehrere Dateien aufteilen.

split -l 1000 output_file

oder noch besser einfach mal probieren

command | split -l 1000 -

Dadurch wird der Ausgabestream in Dateien mit jeweils 1000 Zeilen aufgeteilt (Standard sind 1000 Zeilen ohne Option -l).

Mit dem folgenden Befehl können Sie dem Dateinamen, der beim Generieren und Aufteilen der Ausgabe zum Speichern in der Datei generiert wird, ein Präfix hinzufügen oder durchsetzen.

command | split -l 1000 - small-


Ich war verwirrt, und für andere ist es split [arguments...] [input e.g. "-" for stdin] [output_prefix]zum Beispiel so, tar -c somedir | split --byes 100MB --numeric-suffixes --suffix-length=3 - somedir.tar.part-dass ein Bündel von 100-MB-Dateien mit den Namen somedir.tar.part-000001, 002 und so weiter ausgegeben wird .
ThorSummoner

3

Sie können ein Bash-Skript verwenden lines.bash

#!/bin/bash
a=0
while IFS='' read -r line
do
  printf -v filename "%04d.txt" "$((a++/1000))"
  echo "$line" >> $filename
done

und benutze es als:

cat long_file.txt | bash lines.bash

Das einzige Problem, das mir aufgefallen ist, ist die *Anmeldung long_file.txt(jemand könnte es korrigieren).


2
Setzen Sie die Option IFSauf leere Zeichenfolge, um das Aufteilen von Wörtern zu vermeiden read. Verwenden Sie -rdiese Option, um das Entstehen von Backslash zu deaktivieren read. Entfernen -e, um ein Entweichen des Backslashs zu vermeiden echo. Verwenden Sie Anführungszeichen, um das Teilen von Wörtern zu vermeiden echo. Verwenden Sie -vin bashsince 4.0 zu vermeiden , dass ein Teilprozess zu starten. Verwenden Sie die Post-Inkrementierung, da Ihr aktueller Code in der ersten Datei nur 999 Zeilen enthält. a=0; while IFS='' read -r line; do printf -v filename "%04d.txt" $((a++/1000)); echo "$line" >> "$filename"; done
Handarbeit

@manatwork Danke. Nur mein Schalter printfhat nicht -v. ( bash 4.2.10). Zumindest ist es nicht in der Manpage vonprintf
xralf

1
man printfdocuments / usr / bin / printf, die niemals im Leben eine Umgebungsvariable setzen könnten. Weitere help printfInformationen zur integrierten printfShell finden Sie in der Dokumentation.
Handarbeit

@manatwork OK. Es scheint noch einen Syntaxfehler im ++/Teil zu geben.
Xralf

1
Eine weitere Sache: Es ist nicht erforderlich, Sigil in der arithmetischen Auswertung zu verwenden, es sei denn, Sie benötigen eine explizite Parametererweiterung. Bei der arithmetischen Erweiterung werden die Variablen trotzdem ausgewertet.
Manatwork
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.