How do I create an array from a file using every 3rd line

A file contains the following information shown below. Every ceName has 2 consecutive lines that have to be evaluated, using awk, sed, cut (any common unix tools).

Input file:

ceName: Node-1
processName: tzMgmt
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: tzMgmt
Status: PROCESS_RUNNING
ceName: Node-1
processName: XDM
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: XDM
Status: PROCESS_RUNNING

To become:

processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt              PROCESS_NOT_RUNNING        PROCESS_RUNNING
XDM                  PROCESS_NOT_RUNNING        PROCESS_RUNNING

Any advice appreciated.

Thanks,

Bjoern

To keep the forums high quality for all users, please take the time to format your posts correctly.

First of all, use Code Tags when you post any code or data samples so others can easily read your code. You can easily do this by highlighting your code and then clicking on the # in the editing menu. (You can also type code tags

```text
 and 
```

by hand.)

Second, avoid adding color or different fonts and font size to your posts. Selective use of color to highlight a single word or phrase can be useful at times, but using color, in general, makes the forums harder to read, especially bright colors like red.

Third, be careful when you cut-and-paste, edit any odd characters and make sure all links are working property.

Thank You.

The UNIX and Linux Forums

Thanks for the reply, but the text you put into [code - /code] is not really code but text.

Regards,

Bjoern

Try this and see if you can modify it to your requirement:

sed 'N;N;N;N;N;s/\n/\t\t/gp' file

FYI: You put your data / input / output etc also between

This will make it easy to read.

---------- Post updated at 11:33 PM ---------- Previous update was at 05:27 PM ----------

This works, but not the best way.
Lets see if any one else comes up with a better one.
sed  '/ceName:.*/d; s/^[^:]*: //' 3rdline.txt | sed 'N;N;N;s/\n/\t/g; s/\(^[^\t]*\t[^\t]*\t\)[^\t]*\t\([^\t]*\)$/\1\2/'

Please read the rules.

This is a little more refined:

sed  '/ceName:.*/d; s/^[^:]*: //' 3rdline.txt | sed 'N;N;N;s/\n/\t/g; s/\([^\t]*\t\)//3'

Hi I just did a simalar thing and ended up using awk you might find this a lot simpler Eg:

awk 'ORS=NR%3?"~":"\n"' alltr.out > alltr.sql
my %hash;
local $/="RUNNING";
while(<DATA>){
	if(/ceName: ([^ \n]*).*processName: ([^ \n]*).*Status: ([^ \n]*)/ms){
		$hash{$2}->{$1}=$3;
	}
}
print "processName        Status Node-1                   Status Node-2\n";
print "-----------        -------------------              -------------------\n";
foreach my $key (keys %hash){
	print $key,"  ";
	foreach my $k(keys %{$hash{$key}}){
		print $hash{$key}->{$k},"   ";
	}
	print "\n";
}
__DATA__
ceName: Node-1
processName: tzMgmt
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: tzMgmt
Status: PROCESS_RUNNING
ceName: Node-1
processName: XDM
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: XDM
Status: PROCESS_RUNNING

Thanks for your efforts, edidataguy. However, the result is the following:

sed  '/ceName:.*/d; s/^[^:]*: //' 3rdline.txt | sed 'N;N;N;s/\n/\t/g; s/\(^[^\t]*\t[^\t]*\t\)[^\t]*\t\([^\t]*\)$/\1\2/'
tzMgmttPROCESS_NOT_RUNNINGttzMgmttPROCESS_RUNNING
XDMtPROCESS_NOT_RUNNINGtXDMtPROCESS_RUNNING

Regards,

Bjoern

---------- Post updated at 01:32 PM ---------- Previous update was at 01:29 PM ----------

Thanks for the reply, RadRod. However, this command resulted in a syntax error:

# awk 'ORS=NR%3?"~":"\n"' alltr.out
awk: syntax error near line 1
awk: bailing out near line 1

Regards,

Bjoern

---------- Post updated at 01:56 PM ---------- Previous update was at 01:32 PM ----------

Hi summer_cherry.

Thanks for your help. Which shell was this run on? My system is running on Solaris 10. I called the script with your code 'procheck'; here are my results:

# ./procheck
./procheck[3]: my:  not found
./procheck[3]: $/=RUNNING: is not an identifier

Regards,

Bjoern

Try to use gawk or nawk instead of awk.

 
Thanks for your efforts, edidataguy. However, the result is the following:
tzMgmttPROCESS_NOT_RUNNINGttzMgmttPROCESS_RUNNINGXDMtPROCESS_NOT_RUNNINGtXDMtPROCESS_RUNNING

Sorry, could not come back to you early. Got tied up.
OK. Looks like there is as issue with your version of sed recognizing the "\t" (tab) and \n (new line). Try it this way, replace all \t with [\\t](file://\\t) and \n with [\\n](file://\\n). See if it works.

Hi,

If I may chip in here, summer_cherry's script is written in Perl. So you will have to feed your "procheck" file to the perl interpreter.

First check if perl exists in your system. On my box:

$ 
$ which perl
/usr/bin/perl
$ 
$ perl -v

This is perl, v5.10.0 built for i486-linux-gnu-thread-multi

Copyright 1987-2007, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

$ 

And then run the "procheck" file thusly:

$ 
$ cat procheck
my %hash;
local $/="RUNNING";
while(<DATA>){
    if(/ceName: ([^ \n]*).*processName: ([^ \n]*).*Status: ([^ \n]*)/ms){
        $hash{$2}->{$1}=$3;
    }
}
print "processName        Status Node-1                   Status Node-2\n";
print "-----------        -------------------              -------------------\n";
foreach my $key (keys %hash){
    print $key,"  ";
    foreach my $k(keys %{$hash{$key}}){
        print $hash{$key}->{$k},"   ";
    }
    print "\n";
}
__DATA__
ceName: Node-1
processName: tzMgmt
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: tzMgmt
Status: PROCESS_RUNNING
ceName: Node-1
processName: XDM
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: XDM
Status: PROCESS_RUNNING
$ 
$ perl procheck
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING   
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING   
$ 
$ 

Alternatively, if you add the perl "shebang" at the top of your file and if you have made it executable, then you will be able to run it successfully the way you invoked it.

$ 
$ head -3 procheck
#!/usr/bin/perl
my %hash;
local $/="RUNNING";
$ 
$ chmod 744 procheck
$ 
$ ./procheck
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING   
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING   
$ 
$ 

HTH,
tyler_durden

Hi editaguy. I don't think the problem's with sed:

 
# sed  '/ceName:.*/d; s/^[^:]*: //' 3rdline.txt | sed 'N;N;N;s/\n/\\t/g; s/\([^\\t]*\\t\)//3'
tzMgmt\tPROCESS_NOT_RUNNING\ttzMgmtPROCESS_RUNNING
XDM\tPROCESS_NOT_RUNNING\tPROCESS_RUNNING

There are additional '\t's now. I think I may have to resort to arrays.

Bjoern

Thanks tyler, it works now!

# ./procheck
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING

One question: I'm not familiar with perl, if the _DATA_ is an external file, how do I reference it in the script?

Thanks again,

Bjoern

Let's assume your data is in a file called "data.txt".

$
$ cat data.txt
ceName: Node-1
processName: tzMgmt
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: tzMgmt
Status: PROCESS_RUNNING
ceName: Node-1
processName: XDM
Status: PROCESS_NOT_RUNNING
ceName: Node-2
processName: XDM
Status: PROCESS_RUNNING
$

Then the file handle in the "procheck" script could be changed to "<>", if you pass the data stream to "procheck".

So, "procheck" now looks like this -

$
$ cat procheck
#!/usr/bin/perl
my %hash;
local $/="RUNNING";
while(<>){
    if(/ceName: ([^ \n]*).*processName: ([^ \n]*).*Status: ([^ \n]*)/ms){
        $hash{$2}->{$1}=$3;
    }
}
print "processName        Status Node-1                   Status Node-2\n";
print "-----------        -------------------              -------------------\n";
foreach my $key (keys %hash){
    print $key,"  ";
    foreach my $k(keys %{$hash{$key}}){
        print $hash{$key}->{$k},"   ";
    }
    print "\n";
}
$
$

Note the change in red color.

And you run the script thusly -

$
$ # Method 1
$
$ cat data.txt | ./procheck
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING
$
$
$ # Method 2
$
$ ./procheck < data.txt
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING
$
$

Alternatively, if you do not want to pass the data from your file (via pipe or redirection), then you'll have to open the file explicitly in your script.

Assuming the file "data.txt" is in the same directory as "procheck", you'd have this -

$
$ cat procheck
#!/usr/bin/perl
my %hash;
local $/="RUNNING";
open(INPUT, "data.txt") or die "Can't open data.txt: $!";   # open the file for reading
while(<INPUT>) {                                            # loop through the records
    if(/ceName: ([^ \n]*).*processName: ([^ \n]*).*Status: ([^ \n]*)/ms){
        $hash{$2}->{$1}=$3;
    }
}
print "processName        Status Node-1                   Status Node-2\n";
print "-----------        -------------------              -------------------\n";
foreach my $key (keys %hash){
    print $key,"  ";
    foreach my $k(keys %{$hash{$key}}){
        print $hash{$key}->{$k},"   ";
    }
    print "\n";
}
close(INPUT) or die "Can't close data.txt: $!";             # done; close the file now
$
$ ./procheck
processName        Status Node-1                   Status Node-2
-----------        -------------------              -------------------
tzMgmt  PROCESS_NOT_RUNNING   PROCESS_RUNNING
XDM  PROCESS_NOT_RUNNING   PROCESS_RUNNING
$
$

HTH,
tyler_durden

Tyler, you made my day!:smiley: The last method without piping or redirection is what I was looking for.

Thanks so much,

Bjoern