1820038 Members
3080 Online
109608 Solutions
New Discussion юеВ

how get two lines ...

 
SOLVED
Go to solution
Manuales
Super Advisor

how get two lines ...

Hi all ..
this is the scenario .. i have a files whit this information

cat information.txt

uno- this is a cat
dos- this is a dog

uno- this is a cat
dos- this is a duck

uno- this is a cat
dos- this is a cat

uno- this is a dog
dos- this is a cat

uno- this is a duck
dos- this is a pig

uno- this is a pig
dos- this is a pig

I need to compare both lines toguehter.
if you see they are separated by a line, i need to see if the column 5 is the same or not for each two lines, how can i do that?

how can i get the lines uno- dos- after one line ?

i mean i need to get first:

uno- this is a cat
dos- this is a dog
how can i get them?
after i need to compare the column 5 , i know how to do that
then after a white line i need to get these lines ...
uno- this is a cat
dos- this is a duck

and go on ..
please let me know...
i think i can do it with awk, i do not know how exactly to use it to get the information as i need it ..

thanks in advace.
Manuales.
25 REPLIES 25
James R. Ferguson
Acclaimed Contributor
Solution

Re: how get two lines ...

Hi:

# awk 'NF==0 {next};{getline LINE;split(LINE,A);if ($5==A[5]) {print $0"\n"LINE}}' file
uno- this is a cat
dos- this is a cat
uno- this is a pig
dos- this is a pig

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

thanks James

how can i stop the first two lines to get the value of the column 3 ... and then stop for the other 2 and go on ..?
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi (again) Manuales:

> how can i stop the first two lines to get the value of the column 3 ... and then stop for the other 2 and go on ..?

I'm not sure I understand what you are asking. If you want the third field and not the fifth, the logic would look like:

# awk 'NF==0 {next};{getline LINE;split(LINE,A);if ($3==A[3]) {print $0"\n"LINE}}'

This code skips blank lines (i.e those that have no fields: NF==0). Otherwise, we have the first line we want in '$0'. The next LINE is fetched with 'getline' into the 'LINE' variable. Since 'getline' doesn't do auto-field-spliiting, we do it with a 'split' ourselves.

Regards!

..JRF...
Manuales
Super Advisor

Re: how get two lines ...

i mean

for .....
what you told me:
awk 'NF==0 {next};{getline LINE;split(LINE,A);if ($5==A[5]) {print $0"\n"LINE}}' file.txt

a=column 5 from uno-
b=column 5 form dos_

if [[ $a = $b ]]
then
echo $ > output.txt
fi


done
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi (again) Manuales:

> what you told me:

I don't understand what you are asking. Did you try running the code I suggested using *your* input as posted; and did it produce the output you wanted?

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

ok i will explain better

once i have got the first 2 lines the script has to stop to get the value of the column 5 of the line where appears "uno_" and keep it in a variable a, then the script will get the
line where appears "dos_" , will keep the value in the variable b, then a and b will be compared, if they are similar $a will be send to an output file ....

then i need to do the same to the other two lines and go on ....


until the script has red all the file ..
Manuales
Super Advisor

Re: how get two lines ...

yes, i ran the code you gave me and worked i got all the lines i want ..... but i need to code in order to stop each two lines uno_ and dos_ and do what above i wrotte ... ow can i do that, how can i stop each two lines for being evaluated?
Manuales
Super Advisor

Re: how get two lines ...

i think i have to use something like this ..


awk 'BEGIN { }
{
...................
..................

a=`echo $line that contains the word uno_ | cut -d" " -f`

b=`echo $line that contains the word dos_ | cut -d" " -f`

if [[ $a = $b ]]
then
echo $a > output.txt
fi
...................
..................



}
}' file

it is a loop of the code you gave me for each two lines uno_ and dos_

space

the the others lines uno_ and dos_

and go on ...

how can i do that?
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi Manuales:

> once i have got the first 2 lines the script has to stop to get the value of the column 5 of the line where appears "uno_" and keep it in a variable a, then the script will get the
line where appears "dos_" , will keep the value in the variable b, then a and b will be compared, if they are similar $a will be send to an output file ....

Look at the 'awk' script I suggested. You said in your opening comments, "I think I can do it with awk...".

The script I have offered skips blank lines; reads two lines; and "stops" at that point if you want to think of it that way. The 5th field of one record is compared for equality to the 5th field of the second record just as you have asked. In the case of the 'awk' records, '$5' is one variable and 'a[5]' is the other.

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

ok.. what you tell me helps a lot, let me give you more detail:

i have this file called information.txt

uno- Ana has a cat
dos- Pedro has is a dog

uno- Paulina has a pig
dos- Jorge has is a pig

uno- Robert has a cat
dos- Jay has is a pig


i want to go first the 2 lines that contain uno_ and dos_
uno- Ana has a cat
dos- Pedro has is a dog

if Ana (line that contains word uno_) has the same animal than Pedri (line that contains word dos_)have the same animal the script has to report that in an output file.

then
the script has to go to the next 2 lines and do the same:
if Paulina (line that contains word uno_) has the same animal than Jorge(line that contains word dos_)have the same animal the script has to report that in an output file.

until finish to read the file information.txt

at the end i will get an output file

is it more clear? :)
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi:

Using your last example, the field representing the animal is field-5 in the "uno" records and field-6 in the "dos" records. If that is intentional, then:

# awk 'NF==0 {next};{getline LINE;split(LINE,A);if ($5==A[6]) {print $0"\n"LINE}}' file > file.out

# cat file.out
uno- Paulina has a pig
dos- Jorge has is a pig

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

correct, i have to create a file with that name of animal where those two lines have the same animal ......

if i have this file, how can i do that?

uno- Ana has a cat
dos- Pedro has is a dog

uno- Paulina has a pig
dos- Jorge has is a pig

uno- Robert has a cat
dos- Jay has is a pig

uno- Teresa has a butterfly
dos- Hector has is a butterly


thanks.

Manuales
Super Advisor

Re: how get two lines ...

this is the correct file (i missed an "f" in the last line")

where do you say "touch > $anmal "
in theory the script has to create two files with the name pig and butterfly


uno- Ana has a cat
dos- Pedro has is a dog

uno- Paulina has a pig
dos- Jorge has is a pig

uno- Robert has a cat
dos- Jay has is a pig

uno- Teresa has a butterfly
dos- Hector has is a butterfly

thanks.
Manuales
Super Advisor

Re: how get two lines ...

I have another scenario with a similar issue:

this is the file with the information:

______

S1: /folder1 lrwxrwxrwt root sys
S2: /folder1 lr-xr-xr-x bin bin

S1: /folder2 drwxrwxrwx bin bin
S2: /folder2 dr-xr-xr-x bin bin

S1: /home drwxrwxrwx decadm sapsys
S2: /home drwxr-xr-x root root

S1: /home/user1 drwx------ user3 sapsys
S2: /home/user1 drwx------ root sapsys

______

S1=server1
S2=server2


i have the correct user and group in server1
i have to fix the user and group in server2.

for the first 2 lines i have this:
S1: /folder1 lrwxrwxrwt root sys
S2: /folder1 lr-xr-xr-x bin bin

For the line where appears "/folder1" and S2: if the column 4 is different
to the column 4 in line where appears S1: and "/folder1" then the script will send this line in an output file:
echo "chown root:sys /folder1" >> changeuser.sh

at the end i will run the file changeuser.sh to change all what is different in S2.

how can i do this?






Manuales
Super Advisor

Re: how get two lines ...

i forget to mention, if the group or user is different between line 1 where says S1: and line2 where says S2: knowing that the line1 where is S1: has the correct user and group then i should have finally:
echo "chown root:sys /folder1" >> changeuser.sh
echo "chown decadm:sapsys /home" >> changeuser.sh
echo "chown user3:sapsys /home" >> changeuser.sh

cat changeuser.sh
chown root:sys /folder1
chown decadm:sapsys /home
chown user3:sapsys /home
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi (again) Manuales:

> in theory the script has to create two files with the name pig and butterfly

Well, you never made that clear at the onset! That said:

# awk 'NF==0 {next};{getline LINE;split(LINE,A);if ($5==A[6]) {FILE=$5;print $0"\n"LINE>>FILE;close FILE}}' file

...will create output files named for the animal names in your example consisting of the lines with matching entries in two adjacent records of the input file.

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

ok, that is i want .... thank you so much ...

could you help me with the other scnenario? i want to practice more awk for this kind of things .. thanks...
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi Manuales:

> could you help me with the other scnenario?

OK, but this is very similar, so before trying what I am offering, I urge you to *try* and write a solution yourself!

That said, you could do:

# awk 'NF==0 {next};$3~/l/ {next};{getline LINE;split(LINE,A);if ($4!=A[4]) {print "chown "$4":"$5,$2> "changeuser.sh"}}'

Notice that we skip records that specify a symbolic link notation. That's because the permissions and ownerships of symbolic links don't matter. It's the object to which the link points that does.

I would also point out that a simple '>' instead of a '>>' suffices in both this script and the one I previously provided.

Regards!

...JRF...
Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

thank you so much :) .... i will work hard on this to avoid asking ....

also, i want to evaluate if $4 or $5 are different .... how can i do that, i try this it did not work ...

;if ($4!=A[4])||($5!=A[5]) {print "chown "$4":"$5,$2

;if ($4!=A[4])or($5!=A[5]) {print "chown "$4":"$5,$2

please help :0]
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi:

> ;if ($4!=A[4])||($5!=A[5]) {print "chown "$4":"$5,$2

The entire condition to be evaluated needs to be in parenthesis. The '||' means "or". Hence:

...if (($4!=A[4])||($5!=A[5])) {...

...works.

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

nice !!!

i make user $2 = $2 in both lines i wrotte this:


if ( ($2=A[2])&&(($4!=A[4])||($5!=A[5])))


also i found this format:
$ awk '{
if ($3 =="" || $4 == "" || $5 == "")
print "Some score for the student",$1,"is missing";'
}' student-marks



i will test it too ... thank you so much, i will promise to read more of awk, really is POWERFUL !!!
thanks.
Manuales
Super Advisor

Re: how get two lines ...

last question of this topic

how would you code if you do not want to change permission in case line S1 in its column 4 has a number?

In this case A, yes, i want to chage the user and group, the owner which is a number does not belong to S1.
S1: /fold5 drwxr-xr-x root group2
S2: /fold5 drwxr-xr-x 345 group1
i will use what you told me:

cat file | grep -v ">" | awk 'NF==0 {next};$3~/l/ {next};{getline LINE;split(LINE,A); if (($2=A[2])&&(($4!=A[4])||($5!=A[5]))){print "chown "$4":"$5,$2> "changeuser.sh"}}'



for this case B, i do not want the user and group of S2:
S1: /fold1 drwxr-xr-x 234 root
S2: /fold1 drwxr-xr-x user1 daemon

S1: /fold5 drwxr-xr-x root 345
S2: /fold5 drwxr-xr-x user3 group1

what shold add in the line to consideer the case B too?

something like this:
if ( $4!= of a number only in line S1:) DO NOT DO ANYTHING, else (($2=A[2])&&(($4!=A[4])||($5!=A[5])))

THANKS
James R. Ferguson
Acclaimed Contributor

Re: how get two lines ...

Hi Manuales:

> how would you code if you do not want to change permission in case line S1 in its column 4 has a number?

Use pattern matching:

# awk 'NF==0 {next};$3~/^l/ {next};$4~/^[0-9]$*/ {getline;next};{getline LINE;split(LINE,A);if (($4!=A[4])||($5!=A[5])) {print "chown "$4":"$5,$2> "changeuser.sh"}}'

I have build onto what we already have. If the 4th field is *all* digits (0-9) then get the next record (the 'getline'; but do nothing with it; and start the whole cycle again (the 'next').

Regards!

...JRF...
Manuales
Super Advisor

Re: how get two lines ...

another last thing, i want to use awk for this other evaluation ..
how can i change the permission,
sorry , i want to learn to use awk and i know this will help me a lot ...

i have to review the permision between these two lines ..

S1: /folder2 drwxrwxrwx bin bin
S2: /folder2 dr-xr-xr-x bin bin


for the first one i have drwxrwxrwx, so /folder2 has to be changed as:
chmod 777 /folder2 ...

i do not want to change the permission, i only want to send a line to other output file named "changepermission.txt" saying:

/folder2 actual_permission correct_permission

it means:

/folder2 dr-xr-xr-x drwxrwxrwx

how can i code to generate other other output file?

thanks :=)