Aufteilen einer Datei: Ersetzen Sie "egrep" in "sed"

262
ChemMod

Ich möchte meine $ -Datei mit x Zeilen in zwei Hälften teilen und überprüfen, wie viele Zeilen in einem Protokoll " tot " sind. Ich habe mit folgendem begonnen:

half=`expr $(egrep -c . $file) / 2`  sed -n 1,$p $file |  xargs echo $file $half $(egrep -c dead $I) > log_1 sed -n $,$p |  xargs echo $file $half $(egrep -c dead $I) > log_2 

Die Ausgabe für den ersten sedBefehl ist in Ordnung, aber beim Ersetzen egrepim Bereich des Befehls ist ein Fehler sedaufgetreten:

DeadOrAlive 5 2 -bash: $,$p: bad substitution 

Gibt es eine effizientere Möglichkeit, die Datei aufzuteilen bash?

0
`$ (...)` und `$ {...}` sind unterschiedliche Konstrukte. Ersteres ist Befehlssubstitution, letzteres ist Parametererweiterung. choroba vor 6 Jahren 0
Ihre erste "egrep" zählt nicht leere Zeilen. `grep -c ^ file` würde die Gesamtzahl der Zeilen einschließlich leerer Zeilen erzeugen. (Wenn Ihre Datei keine leeren Zeilen enthält, sind beide natürlich gleichwertig.) `Wc -l tripleee vor 6 Jahren 0
Was erwarten Sie von `$ I`? tripleee vor 6 Jahren 0
`sed" $ half, \ $ "` wählt Zeilen von "$ half" bis zum Ende der Datei aus, obwohl Ihr Code die mittlere Datei (Zeilennummer "$ half") sowohl in der ersten als auch in der zweiten Hälfte enthält. tripleee vor 6 Jahren 0
`sed" 1, $ d "Datei` löscht die ersten '$ half'-Zeilen und druckt den Rest aus. Damit können Sie die Datei richtig in zwei nicht überlappende Partitionen aufteilen. tripleee vor 6 Jahren 0

2 Antworten auf die Frage

0
agc
  1. Verwenden wcund headund tail:

    half=$(( $(wc -l "$file")/2 )) head -$half | egrep -c dead | xargs echo "$file" $half > log_1 tail -$half | egrep -c dead | xargs echo "$file" $half > log_2 
  2. Mit split:

    split -a1 --numeric-suffixes=1 -n 'l/2' "$file" "$file"_ echo "$file" "$file"_1 $(egrep -c dead "$file_1") > log_1 echo "$file" "$file"_2 $(egrep -c dead "$file"_2) > log_2 rm "$file"_[12] 
0
tripleee

Hier ist eine Awk-Lösung.

awk '/dead/ { a[++n] = NR } END { for (i=1; i<=n; i++) if (a[i] > NR/2) break print ARGV, int(NR/2), i-1 >"log_1"; print ARGV, int(NR/2)+(int(NR/2)!=NR/2), n-i+1 >"log_2" }' file 

Wir sammeln im Array adie Zeilennummern der Übereinstimmungen. Wir ermitteln dann, wie viele der Zeilennummern im Array kleiner als die mittlere Zeile sind. Ihre Zählung wird der ersten Partition zugewiesen. (Wir müssen verwenden, i-1da wir den Partitionierungspunkt bereits überschritten haben, wenn wir breakdie Schleife verlassen.)

Im Allgemeinen möchten Sie vermeiden, dass dieselbe Datei mehrmals gelesen wird, insbesondere wenn sie groß ist. und zweitens versuchen Sie, die Anzahl der Prozesse zu minimieren.

Es ist nicht klar, was das mittlere Ausgabefeld enthalten soll. Wenn die Datei eine ungerade Anzahl von Zeilen enthält, enthält die erste "Hälfte" eine Zeile weniger als die zweite Partition. (Dies ist nicht schwer zu ändern, aber Sie müssen sich auf die eine oder andere Weise entscheiden.)

Streng genommen sollten wir die Dateien, die wir öffnen, schließen () `, aber solange es nur zwei gibt, habe ich mich nicht darum gekümmert. tripleee vor 6 Jahren 0