Ich möchte meine$DateienthaltendXZeilen in zwei Hälften und prüfen Sie, wie viele Zeilen "tot" in einem Protokoll. Ich begann mit dem Folgenden:
half=`expr $(egrep -c . $file) / 2`
sed -n 1,${half}p $file |
xargs echo $file $half $(egrep -c dead $I) > log_1
sed -n ${half},${egrep -c . $file}p |
xargs echo $file $half $(egrep -c dead $I) > log_2
Die Ausgabe für den ersten sed
Befehl ist in Ordnung, aber beim Ersetzen egrep
im Bereich von sed
geht es schief:
DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution
Gibt es eine effizientere Möglichkeit, die Datei aufzuteilen bash
?
Antwort1
Verwenden von
wc
,head
undtail
: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
Verwendung von
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]
Antwort2
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 die Zeilennummern der Übereinstimmungen im Array a
. Dann ermitteln wir, wie viele der Zeilennummern im Array kleiner sind als die mittlere Zeile. Ihre Anzahl wird der ersten Partition zugewiesen. (Wir müssen verwenden, i-1
weil wir den Partitionierungspunkt bereits überschritten haben, wenn wir break
aus der Schleife herauskommen.)
Im Allgemeinen möchten Sie das mehrfache erneute Lesen derselben Datei vermeiden, insbesondere wenn sie groß sein könnte. Und zweitens sollten Sie versuchen, 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. (Das lässt sich nicht schwer ändern, aber Sie müssen sich so oder so entscheiden.)