bash: Fehlermeldung und Werte in Array sortieren?

H

h.nietnagel

Grünschnabel
Hallo,

ich probiere den ganzen Tag schon mir bestimmte Teile aus einer Riesentextdatei ausgeben und in mehrere kleine Dateien schreiben zu lassen.
Diese Riesentextdatei enthält ein paar Zeilen mit Text und wird in unregelmäßigen Abständen mit einer Art Kopfzeile unterbrochen. Diese Kopfzeilen verwende ich als Erkennungsmerkmal für die Zeilen. In diesen Kopfzeilen ist jeweils eine der Zahlenfolge aus dem arrayEins enthalten und jede dieser Zahlenfolgen, d.h. 001 z.B., tritt insgesamt 4mal in der Datei auf.
Hier der - sicher sehr umständliche - Code:

Code:
#!/bin/bash

declare dir=Test
if [ ! -d $dir ]; then
mkdir $dir; fi

arrayEins=(001 002 003 004 005 006 008 009 010 011)

for ((i=0; i<${#arrayEins[@]}; i++))
do
	sed -ne '1,20p' test.txt > $dir/tmp.txt	
	sed '19s/40/4/g' $dir/tmp.txt > $dir/Ergebnis${arrayEins[$i]}Datei.txt
	rm $dir/tmp.txt
	j=${arrayEins[${i}+1]}
declare -a tmparr
	tmparr=("Blabla: blub${arrayEins[$i]}_links" "Blabla: blub${arrayEins[$i]}_rechts" "Blabla: blub${arrayEins[$i]}_oben" "Blabla: blub${arrayEins[$i]}_unten")	
	declare -a temparr
	temparr[0]=`grep -n "${tmparr[0]}" test.txt | tail -1 | cut -d':' -f1`
	temparr[1]=`grep -n "${tmparr[1]}" test.txt | tail -1 | cut -d':' -f1`
	temparr[2]=`grep -n "${tmparr[2]}" test.txt | tail -1 | cut -d':' -f1`
	temparr[3]=`grep -n "${tmparr[3]}" test.txt | tail -1 | cut -d':' -f1`	
	if [ "${arrayEins[$i]}" -eq 011 ]; then
		tmp=`sed -ne '$p' test.txt`
		temp=`grep -n "${tmp}" test.txt | tail -1 | cut -d':' -f1`
		letzte=`expr ${temp} - 2`
	else
	    tmparr[4]=`grep "Blabla: blub${arrayEins[$j]}" test.txt| head -1 | tail -1`
		temparr[4]=`grep -n "${tmparr[4]}" test.txt | tail -1 | cut -d':' -f1`	
		letzte=`expr ${temparr[4]} - 2`		
	fi
	sed -ne "${temparr[0]},${letzte}p" test.txt >> $dir/Ergebnis${arrayEins[$i]}Datei.txt
done

echo
Das funktioniert auch, bis auf 2 Sachen.

Das erste ist ein Fehler:
Code:
bash: value too great for base (error token is "008")
Ich hab schon gegoogelt und die Erklärung gefunden, dass es irgendwas mit dem Logarithmus zu tun hat(?) Sorry, ich bin kein Mathegenie :frage:
Aber ich finde keine Lösung.
Ich hab schon versucht, nur einfache (also ohne vorangestellte "0") Zahlen in dem arrayEins zu verwenden und dann als ersten Schritt in der Schleife die "00" vor die Zahlen zu setzen. Aber das funktioniert auch nicht.
Ich hab halt den Grund für den Fehler noch nicht verstanden. Und wie kann ich das Problem lösen?

Die zweite Frage betrifft das
Code:
temparr
Wie kann ich mir die darin enthaltenen Werte aufsteigend sortieren lassen? Geht das überhaupt?

Vielen Dank im Voraus für Hilfe und Tipps!


Schöne Grüße,
Hannes
 
Zuletzt bearbeitet:
Ohne mich jetzt voll und ganz dem Skript gewidmet zu haben (das Einlesen dauert einfach sehr lange) kann es sein, dass dir einfach nur die 007 in deinem Array fehlt?
 
Wäre es vielleicht Möglich, uns so eine "Riesentextdatei" oder zumindest ein Teil mit dieser "Kopfzeile" zur Verfügung zu stellen?

So wäre die Problemlösung wahrscheinlich um einiges einfacher, da sich nicht jeder in dein Script einlesen muss. Noch dazu sollte das mit sehr viel weniger Code realisierbar sein.
 
Hi,

zunächst einmal: der Fehler ("bash: value too great for base (error token is "008")") tritt wohl in dieser Zeile auf:
Code:
tmparr[4]=`grep "Blabla: blub${arrayEins[$j]}" test.txt| head -1 | tail -1`
Das ist auf den ersten Blick die einzige Stelle, an der "$j" als Zahl interpretiert wird. Wegen der führenden Nullen versucht die Shell, "008" als Oktalwert auszuwerten, und stolpert dabei natürlich über die 8.

Eventuell reicht es ja schon, mit der Angabe der Basis sicherzustellen, dass das als Dezimalzahl verstanden wird, also etwa:
Code:
tmparr[4]=`grep "Blabla: blub${arrayEins[10#$j]}" test.txt| head -1 | tail -1`

Das gibt natürlich Schwierigkeiten, wenn die dargestellten Werte und die Indizes auseinanderlaufen, die Differenz also wegen der fehlenden "007" plötzlich 2 statt 1 ist.

Sonst sollte es durchaus möglich sein, den Array mit den Werten für i ohne die '0'en am Anfang zu definieren und in der Schleife zunächst $j zu bestimmen und danach(!) die Nullen an $i und $j voranzustellen.

Zum zweiten: einen Array (im Beispiel numerisch) zu sortieren, sollte eigentlich mit
Code:
temparr=($(echo "${temparr[*]}" | tr " " "\012" | sort -n))
möglich sein.

Zu sed: um die ersten 20 Zeilen aus einer test.txt zu lesen, in Zeile 19 alle '40' durch '4' zu ersetzen, und das Ergebnis nach $dir/ErgebnisXXX.txt zu lenken, könntest du auch einfach
Code:
sed -e '19s/40/4/g' -e 20q test.txt >$dir/ErgebnisXXX.txt
verwenden. (Damit liest du dann nicht mehr jedesmal die ganze Datei bis zum Schluss ein.)

Und um die Nummer der letzten Zeile in der Eingabedatei zu bestimmen, geht statt
Code:
tmp=`sed -ne '$p' test.txt`
temp=`grep -n "${tmp}" test.txt | tail -1 | cut -d':' -f1`
auch
Code:
temp=`sed -n '$=' test.txt`
oder
Code:
temp=`wc -l <test.txt'

Grüsse,
A.
 
@floyd
Was für eine tolle Hilfe! :)
Hoffe der Threadersteller bekommt das noch mit, der Beitrag ist ja schon ein bisschen älter...
 
@floyd
Was für eine tolle Hilfe! :)
Hoffe der Threadersteller bekommt das noch mit, der Beitrag ist ja schon ein bisschen älter...

Ähm, der Threadersteller hatte tatsächlich nicht mehr damit gerechnet, noch Antworten zu bekommen und meldet sich daher erst so spät 8)
Vielen Dank für die Hilfe!
Meine erste Version funktionierte trotz der Fehlermeldungen. Wenn ich ein bisschen Zeit und Muße finde, werde ich aber die genannten Korrekturvorschläge noch einbauen.

Schöne Grüße,
h.nietnagel
 

Ähnliche Themen

Verschlüsseltes Backup-Script mit rsync

Problem mit HSPA+ Modem Huawei E353 - Installation unmöglich?

Last mit etc/passwd anzeigen lassen

Prozess aus eigenem Init script wird gekillt

eine Schleife einbauen.

Zurück
Oben