alucard7
Goto Top

Mit awk Variablen und Array setzen

Hi an alle,

ich habe ein Problem unter Unix/Aix und zwar versuche ich in einem ksh script Informationen auszulesen mit awk und diese dann in Variablen zu schreiben.

Zum einen soll mit:
date '+%m %y' | awk '{cm=$1; cy=$2}'
der jeweilige monat und das jahr in die variablen cm und cy geschreiben werden, sodass diese weiter in dem script verwendet werden können.

Fals dies gelingt, soll später, mit awk(oder auch mit anderen möglichkeiten) ein Array befüllt werden.

Mein Beispiel-Ansatz ist:
lpstat -l -p$printer | awk 'NR>3{arr[$1]=$2}'

Jedoch funktionieren beide Aufrufe nicht und ich hoffe es liegt nur an der falschen Syntax von meinen awk Aufrufen, sonst wäre ich für andere Varianten sehr dankbar.

Ich hoffe ich habe mich klar genug ausgedrückt, bei Unklarheiten einfach fragen ;)

mfg Alucard7

Content-Key: 164686

Url: https://administrator.de/contentid/164686

Printed on: April 16, 2024 at 09:04 o'clock

Member: micneu
micneu Apr 19, 2011 at 09:46:23 (UTC)
Goto Top
hier das habe ich mal in ksh bei mir getsetet auf einem debian 6

date "+%m %Y" | awk '{ cm=$1; cy=$2; print cy " " cm}'  

nur verstehe ich noch nicht was genau das ziel sein soll?
was soll das ergebnis liefern?
welche informationen, was willst du damit machen?

Gruß michael
Member: Alucard7
Alucard7 Apr 19, 2011 at 18:14:07 (UTC)
Goto Top
Hi micneu,

um es ein bisschen aufzuklären:
Ich will ein script schreiben, das anhand des Datums Einträge findet, die gelöscht werden sollen.
Dabei handelt es sich um Druckaufträge in einer Warteschlange, das aber nur so nebenbei.
Das Problem an diesem Ansatz ist, die Variablen aus awk heraus zu kriegen. Diese sollen später nämlich in der Form "| grep "(cm\..\cy)" ..." verwendet werden, um die angesprochenen Einträge zu finden.
Im späteren Verlauf muss ich auch leider mehrere Einträge der Warteschlange vergleichen und die richtigen ID's, die zum löschen benötigt werden, heraus filtern, wieder in Variablen.
Hier wollte ich zudem mit Arrays arbeiten, da das die schickste Variante ist(schön wäre: " awk '{array[$1]=$2}' ". Problem entsteht durch die Ausgabe der Einträge in mehreren Zeilen:
Bsp.:
datum name rank ...
04\12\11 test.print 123 ...
status id ...
queued 345678 ....

=> weitere Ausgabe in anderem Format um ID und RTank zu verbinden, da ID und Rank/datum nie in einer Zeile stehen
queued 345678 test.print 123 ....

Am Ende soll dann einem Array auf den Index(Rank) die ID gelegt werden => delete ${array[123]}

Ich hoffe ich konnte es etwas verständlicher machen, ich sehe aber wenig Möglichkeiten, dass Array aus awk herauszubekommen.

mfg Alucard7
Member: micneu
micneu Apr 20, 2011 at 07:51:17 (UTC)
Goto Top
du kannst eigentlich das ganze in awk ausführen.
mit
system("befehl")
kannst du dann alle befehle die es in der ksh ausführen lassen.
mit
system("befehl | getline")
kannst du die ausgabe mit awk weiter verarbeiten.

jetz noch eine frage, ich mache nicht so viel mit der "KSH" kann die überhaubt mit arrays umgehen? die bash kann es.
also ich habe gerade mal wikipedia gelesen und so wie ich es deute kann die normale ksh keine arrays.
http://de.wikipedia.org/wiki/Korn-Shell
gruß michael
Member: Alucard7
Alucard7 Apr 20, 2011 at 09:52:16 (UTC)
Goto Top
Hi,
könntest du das ein bisschen konkreter beschreiben?
Ich verstehe nicht ganz wie ich das praktisch verwenden kann.

Zudem ist die ksh, zumindest die von AIX, Array fähig, habe ich schon mehrfach getestet.

mfg Alucard7
Member: micneu
micneu Apr 20, 2011 at 11:47:43 (UTC)
Goto Top
schau mal bitte in dein pm rein

gruß michael
Member: micneu
micneu Apr 26, 2011 at 07:12:37 (UTC)
Goto Top
Guten Morgen,

hier habe erstmal ein kleinen zwischen stand.

#! /usr/bin/awk -f
BEGIN {
	print "Anzahl Argumente in ARGC : " , ARGC-1  
	if(ARGC-1 < 2){
		print "Bitte 2 dateien angeben"  
		exit 1
	}
	DATEI1=ARGV[1]
	DATEI2=ARGV[2]
	#print DATEI1
	#print DATEI2
	print "________________"  
}
# HauptPRG
{
	suchedatei1()

}
END {
	close (DATEI2)
	print "ende des scripts"  
}
function suchedatei1(){
    FS=" "  
    	line[NR]=$0
    	lineDatum[NR]=$1
    	lineDatei[NR]=$3
        suche1=match($0, "02/22")  
        if(suche1){
        	print "Treffer Datum: " NR, lineDatum[NR]   
            print "Line: " NR-1, line[NR-1]  
            #print "Treffer Name Datei1: " NR-1, lineDatei[NR-1] 
            TREFFER = lineDatei[NR-1]
            print TREFFER
			suchedatei2()
            print "=============="  
       }
		
}
function suchedatei2(){
	FS=" "  
#	print "2. datei" 
	while (getline < DATEI2) {
		Zeile[NR]=$0
		ZeileDateiID[NR]=$2
		ZeileDateiName[NR]=$3
		suche2=match($0, TREFFER)
		if (suche2){
			#print "Komplette Zeile: "Zeile[NR] 
			print "DateiID: "ZeileDateiID[NR]  
			print "DateiName: "ZeileDateiName[NR]  
		}
	}
       close (DATEI2)
}

gruß michael
Member: micneu
micneu Apr 26, 2011 at 08:31:18 (UTC)
Goto Top
habe es noch etwas angepasst.
das aktuelle datum wird ermittelt, und zum suchen wird dann der vormonat genommen.

#! /usr/bin/awk -f
##
## bitte gawk installieren
##
BEGIN {
	print "Anzahl Argumente in ARGC : " , ARGC-1  
	if(ARGC-1 < 2){
		print "Bitte 2 dateien angeben"  
		exit 1
	}
	DATEI1=ARGV[1]
	DATEI2=ARGV[2]
	#print DATEI1
	#print DATEI2
	MONAT = strftime ("%m")  
	TAG = strftime ("%d")  
	VORMONAT = strftime ("%m")-1   
	if (length(VORMONAT) == 1){
		VORMONAT = 0VORMONAT
	}
	#print MONAT, TAG, VORMONAT
	print "________________"  
}
# HauptPRG
{
	suchedatei1()

}
END {
	print "ende des scripts"  
}
function suchedatei1(){
    FS=" "  
   	line[NR]=$0
   	lineDatum[NR]=$1
   	lineDatei[NR]=$3
    #suche1=match($0, "03/08") 
    suche1=match($0, VORMONAT"/")  
    if(suche1){
       	print "Treffer Datum: " NR, lineDatum[NR]   
        #print "Line: " NR-1, line[NR-1] 
        #print "Treffer Name Datei1: " NR-1, lineDatei[NR-1] 
        TREFFER = lineDatei[NR-1]
        print TREFFER
		suchedatei2()
        print "=============="  
    }
}
function suchedatei2(){
	FS=" "  
#	print "2. datei" 
	while (getline < DATEI2) {
		Zeile[NR]=$0
		ZeileDateiID[NR]=$2
		ZeileDateiName[NR]=$3
		suche2=match($0, TREFFER)
		if (suche2){
			#print "Komplette Zeile: "Zeile[NR] 
			print "DateiID: "ZeileDateiID[NR]  
			print "DateiName: "ZeileDateiName[NR]  
		}
	}
	close (DATEI2)
}

gruß michael
Member: Alucard7
Alucard7 Apr 26, 2011 at 17:08:33 (UTC)
Goto Top
Hi michael,

Vielen Dank für die schnelle Antwort.
Sobald ich Zeit habe morgen, werde ich mir das genauer ansehen und testen ;)

mfg Alucard7
Member: Alucard7
Alucard7 Apr 27, 2011 at 15:10:09 (UTC)
Goto Top
Hi michael,

ich hab dein Script mal ein bisschen durchgetestet, musste aber leider feststellen, dass in meiner Shell nicht alles so einfach geht:

Da mir nur awk und nicht gawk zur Verfügung steht und der Verwaltungstechnische Aufwand dafür zu groß ist, musss ich auf diese Zeit Funktion verzichten.
Zudem besteht das Porblem, dass ich bei:
line[NR]=$0 lineDatum[NR]=$1 lineDatei[NR]=$3;
auch wieder die mehrfachzeilen erhalte: 1 Eintrag besteht ja aus 3 Zeilen, wovon jedes z.B. 3 Feld dann in einer Ausgabe ausgegeben wird.

Aus diesen Gründen ist mein Ansatz, die Datumsberechnung im normalen Script zu halten und die einzelnen Zeilen mit grep herauszufiltern.
Diese Ausgabe dann in Dateien umleiten und wieder filtern und umleiten.
Am Ende dann die Ergebnisse auslesen und verabreiten, was soweit ganz gut funktioniert, wenn auch nicht so toll aussieht ;) :
cm=`date '+%m'`  
cy=`date '+%y'`  

pruef=`echo $cm | sed 's/.$//'`  
if [[ "$pruef" = "0" ]]; then  
  if [[ "$cm" = "01" ]]; then  
    km=12;
    ky=`expr $cy -1 `;
  else
    zwm=`echo $cm | sed 's/^.//'`;  
    km=`expr $zwm - 1`;
    km=0$km;
    ky=$cy;
  fi
else
  if [[ "$pruef" = "10" ]]; then  
    km=09;
    ky=$cy;
  else
    km=`expr $cm - 1`;
    ky=$cy;
  fi
fi

ls /pfad | sed 's/.*:\(.*\)\$.*/\1/' | sort | uniq >> pqs  

for i in `cat pqs`; do
  qchk -L -P$i | egrep -i -v "(cm/../cy|km/../ky|queue|/var/spool|down)" | awk 'NR>4{print $3}' >> zwi  
  qchk -W -P$i | awk 'NR>3{print $7,$2}' >> zwi2  

  for j in `cat zwi`; do awk -v pru=$j '{if (pru==$1) print $2}' zwi2 >> erg; done  
  for k in `cat erg`; do echo $k; done
  rm zwi
  rm zwi2
  rm erg
done

Durch einige ungünstige Umstände konnte ich das noch nicht richtig in der Praxis testen, werde ich asap aber nachholen.

mfg Alucard7
Member: micneu
micneu Apr 28, 2011 at 19:27:57 (UTC)
Goto Top
läuft auf deinem server perl?
werde versuchen das ganze mal in perl umzusetzen.
die daten zum testen habe ich ja noch.
oder muss das unbedungt in awk sein?

gruß michael
Member: Alucard7
Alucard7 Apr 28, 2011 at 22:31:53 (UTC)
Goto Top
mit perl hab ich mich bisher ncoh nicht befast, kann nciht genau sagen ob perl vorhanden ist.
Werd aber zeitnah bescheid geben, wies aussieht.
Ich bin immer für andere Lösungsmöglichkeiten offen ;)

Grüße Alucard7
Member: micneu
micneu Apr 29, 2011 at 11:55:44 (UTC)
Goto Top
hier mein anfang in perl (noch nicht fertig):

#!/usr/bin/perl
use strict;
use warnings;

our($quelldatei, @Zeilen, $i, $DATEI1INHALT, $CEP, $CEP2);
our($quelldatei2, @Zeilen2, $i2, $DATEI1INHALT2, $CEP3, $CEP4);

$quelldatei = $ARGV or die 'Bitte Quelldatei angeben!';  
open "Q", "<$quelldatei" or die "Datei $quelldatei wurde nicht gefunden";  

$quelldatei2 = $ARGV[1] or die 'Bitte Quelldatei2 angeben!';  
open "Q2", "<$quelldatei2" or die "Datei $quelldatei2 wurde nicht gefunden";  

foreach (<Q>) {
    push @Zeilen, $_;
}

foreach (<Q2>) {
    push @Zeilen2, $_;
}

for ($i=0; $i<=$#Zeilen; $i++){
    if ($Zeilen[$i] =~ /02\//){
        $CEP = $i-1;
        $CEP2 = $i+1;
        print $Zeilen[$CEP]."\n";  
        print "$Zeilen[$i]\n";  
        print $Zeilen[$CEP2]."\n";  
        print "===========================\n";  
    }
}
print "ist erledigt\n";  

es fehlt noch die datums funktion und das prüfen auf die ID.

gruß michael
Member: micneu
micneu Apr 29, 2011 at 12:25:59 (UTC)
Goto Top
so hier mit der Datums funktion:

#!/usr/bin/perl
use strict;
use warnings;

our($quelldatei, @Zeilen, $i, $DATEI1INHALT, $CEP, $CEP2);
our($quelldatei2, @Zeilen2, $i2, $DATEI1INHALT2, $CEP3, $CEP4, $vormonat);

## Datum bearbeiten
##   0      1     2     3     4     5       6       7     8
our($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdat ) = localtime(time);
# Wenn man nur den Monat braucht:
($mon) = (localtime(time))[4];
$mon+=1;
$mon = $mon < 10 ? $mon = "0".$mon : $mon;  
$vormonat = $mon-1;
##

$quelldatei = $ARGV or die 'Bitte Quelldatei angeben!';  
open "Q", "<$quelldatei" or die "Datei $quelldatei wurde nicht gefunden";  

$quelldatei2 = $ARGV[1] or die 'Bitte Quelldatei2 angeben!';  
open "Q2", "<$quelldatei2" or die "Datei $quelldatei2 wurde nicht gefunden";  

foreach (<Q>) {
    push @Zeilen, $_;
}

foreach (<Q2>) {
    push @Zeilen2, $_;
}

for ($i=0; $i<=$#Zeilen; $i++){
    if ($Zeilen[$i] =~ /$vormonat\//){
        $CEP = $i-1;
        $CEP2 = $i+1;
        print $Zeilen[$CEP]."\n";  
        print "$Zeilen[$i]\n";  
        print $Zeilen[$CEP2]."\n";  
        print "===========================\n";  
    }
}
print "ist erledigt\n";  

gruß michael
Member: micneu
micneu May 02, 2011 at 09:30:30 (UTC)
Goto Top
wird zwar nicht mehr benötigt face-smile
aber so ist es vollständig:

#!/usr/bin/perl
## ----------------------------------------------------------------------------
## Script Name: 	
## CreationDate: 	29.04.2011
## Last Modified:	02.05.2011
## Copyright: 		MN (c)2011
## Purpose: 			zeilenweise einlesen von textdateien in ein arry: (Drucker Queue)
## ----------------------------------------------------------------------------
use strict;
use warnings;

our($quelldatei, @Zeilen, $i, $DATEI1INHALT, $CEP1, $CEP2, $T, @L, $L);
our($quelldatei2, @Zeilen2, $i2, $DATEI1INHALT2, $CEP3, $CEP4, $vormonat);
our($L1, $L2, $L3, $L4, $L5, $L6);
our($L_1, $L_2, $L_3, $L_4, $L_5, $L_6);

sub DATUM {
	## Datum bearbeiten
	##	 0		1	  2		3	  4		5		6		7	  8
	our($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdat ) = localtime(time);
	# Wenn man nur den Monat braucht:
	($mon) = (localtime(time))[4];	
	$mon+=1;
	$mon = $mon < 10 ? $mon = "0".$mon : $mon;  
	$vormonat = $mon-1;
	##
	return $mon;
}
DATUM;

$quelldatei = $ARGV or die 'Bitte Quelldatei angeben!';  
open "Q", "<$quelldatei" or die "Datei $quelldatei wurde nicht gefunden";  

$quelldatei2 = $ARGV[1] or die 'Bitte Quelldatei2 angeben!';  
open "Q2", "<$quelldatei2" or die "Datei $quelldatei2 wurde nicht gefunden";  

foreach (<Q>) {
	push @Zeilen, $_;
}


foreach (<Q2>) {
	push @Zeilen2, $_;
}

for ($i=0; $i<=$#Zeilen; $i++){
	if ($Zeilen[$i] =~ /$vormonat\//){
		$CEP1 = $i-1;
		$T = $Zeilen[$CEP1];
		$CEP2 = $i+1;
		print $Zeilen[$CEP1]."\n";  
		print "$Zeilen[$i]\n";  
		print $Zeilen[$CEP2]."\n";  
		print "===========================\n";  
		($L1,$L2,$L3,$L4,$L5,$L6) = split( /\s+/, $T);
		for ($i2=0; $i2<=$#Zeilen2; $i2++){
			if ($Zeilen2[$i2] =~ /$L4/){
				($L_1,$L_2,$L_3,$L_4,$L_5,$L_6) = split( /\s+/, $Zeilen2[$i2]);
				print "ID: ".$L_3. "\n";  
			}
		}
	}
}
print "ist erledigt\n";  
gruß michael