Match a field and move data on the line above...

Match a field and move data on the line above...

am 23.04.2008 10:01:30 von gniagnia

Hi all,

here is an extract of my file :

....
name Paul
age 34
sex male
phone 999333
name Tom
age 26
sex male
phone 444999
name Lisa
age 42
sex female
phone 222777


My aim is to have a shell script that would grab the "age" element and
stick it right after the "name" element (located on the line above...)

Here is a vision of the output i want to generate :

name Paul/34
sex male
phone 999333
name Tom/26
sex male
phone 444999
name Lisa/42
sex female
phone 222777


any idea???

Cheers

Re: Match a field and move data on the line above...

am 23.04.2008 11:20:10 von Dave B

On Wednesday 23 April 2008 10:01, Mr_Noob wrote:

> Hi all,
>
> here is an extract of my file :
>
> ...
> name Paul
> age 34
> sex male
> phone 999333
> name Tom
> age 26
> sex male
> phone 444999
> name Lisa
> age 42
> sex female
> phone 222777
>
>
> My aim is to have a shell script that would grab the "age" element and
> stick it right after the "name" element (located on the line above...)
>
> Here is a vision of the output i want to generate :
>
> name Paul/34
> sex male
> phone 999333
> name Tom/26
> sex male
> phone 444999
> name Lisa/42
> sex female
> phone 222777

Try this:

sed '/^name/ {N;s%\nage %/%}' yourfile

This assumes that the "age" line always follows immediately the "name" line.
If that is not the case, then an awk solution is the next candidate.

--
D.

Re: Match a field and move data on the line above...

am 23.04.2008 12:59:20 von Ed Morton

On 4/23/2008 3:01 AM, Mr_Noob wrote:
> Hi all,
>
> here is an extract of my file :
>
> ...
> name Paul
> age 34
> sex male
> phone 999333
> name Tom
> age 26
> sex male
> phone 444999
> name Lisa
> age 42
> sex female
> phone 222777
>
>
> My aim is to have a shell script that would grab the "age" element and
> stick it right after the "name" element (located on the line above...)
>
> Here is a vision of the output i want to generate :
>
> name Paul/34
> sex male
> phone 999333
> name Tom/26
> sex male
> phone 444999
> name Lisa/42
> sex female
> phone 222777
>
>
> any idea???
>
> Cheers

awk '/^name/{name=$0;next} /^age/{$0=name"/"$2} 1' file

Before you ask - "1" is a true condition which invokes the default action of
printing the current record. You can replace it with "{print $0}" or just
"{print}" if you like.

Ed.

Re: Match a field and move data on the line above...

am 23.04.2008 14:12:31 von gniagnia

perfect! The "age" line follows immediately the "name" line, but i'll
go with 'awk' just in case of...
Thank you very much for your help.

Re: Match a field and move data on the line above...

am 24.04.2008 06:44:44 von Michael Paoli

Mr_Noob wrote:
> here is an extract of my file :
>
> ...
> name Paul
> age 34
> sex male
> phone 999333
> name Tom
> age 26
> sex male
> phone 444999
> name Lisa
> age 42
> sex female
> phone 222777
>
> My aim is to have a shell script that would grab the "age" element and
> stick it right after the "name" element (located on the line above...)
>
> Here is a vision of the output i want to generate :
>
> name Paul/34
> sex male
> phone 999333
> name Tom/26
> sex male
> phone 444999
> name Lisa/42
> sex female
> phone 222777

perl -e '
local $/;
while(<>){
s/^(name [^\n]*)\nage ([^\n]*)/\1\/\2/gm;
print;
}
'

The above perl approach is a bit simplistic - it sucks in all of the
input file before processing it, so it will fail for sufficiently
large
input.

The sed approach below at most stores two adjacent lines, so it will
generally work with large input files - at least if the lines aren't
too
long.

The more complex (and robust) sed logic could likewise be done in
perl,
or the more simplistic perl logic (using pattern or hold space) done
with sed.

sed -ne '

#hold space is Empty or garbage (overwrite it if we need the hold
space)
:e

#if last line:
${
#print patern space:
p
#quit:
q
}

#if not match /^name /
/^name /!{
#print pattern space:
p
#get next line:
n
#branch to e:
b e
}

#(implicit) matched /^name / and not last line
#copy pattern space to hold space:
h
#get next line:
n
#fall through

#Name in hold space
:n
#if match /^age /
/^age /{
#substitute for /^age / nothing in pattern space:
s/^age //
#append pattern space to hold space with embedded newline:
H
#exchange pattern and hold spaces:
x
#substitute for embeded newline / in pattern space:
s/\n/\//
#print pattern space:
p
#if last line, quit:
$q
#get next line:
n
#branch to e:
b e
}
#(implicit) Name in hold space but did not match /^age /
#exchange pattern and hold spaces:
x
#print pattern space:
p
#exchange pattern and hold spaces:
x
#branch to e:
b e
'

Re: Match a field and move data on the line above...

am 24.04.2008 15:01:57 von mop2

Yes, pure shell:

while read L;do
case "${L:0:1}" in n)n=$L;;a)echo $n/${L#* };;*)echo $L;esac
done
This is ok for bash and ...


Mr_Noob wrote:
> Hi all,
>
> here is an extract of my file :
>
> ...
> name Paul
> age 34
> sex male
> phone 999333
> name Tom
> age 26
> sex male
> phone 444999
> name Lisa
> age 42
> sex female
> phone 222777
>
>
> My aim is to have a shell script that would grab the "age" element and
> stick it right after the "name" element (located on the line above...)
>
> Here is a vision of the output i want to generate :
>
> name Paul/34
> sex male
> phone 999333
> name Tom/26
> sex male
> phone 444999
> name Lisa/42
> sex female
> phone 222777
>
>
> any idea???
>
> Cheers

Re: Match a field and move data on the line above...

am 24.04.2008 15:06:04 von mop2

Yes, pure shell:

while read L;do
case "${L:0:1}" in n)n=$L;;a)echo $n/${L#* };;*)echo $L;esac
done

Mr_Noob wrote:
> Hi all,
>
> here is an extract of my file :
>
> ...
> name Paul
> age 34
> sex male
> phone 999333
> name Tom
> age 26
> sex male
> phone 444999
> name Lisa
> age 42
> sex female
> phone 222777
>
>
> My aim is to have a shell script that would grab the "age" element and
> stick it right after the "name" element (located on the line above...)
>
> Here is a vision of the output i want to generate :
>
> name Paul/34
> sex male
> phone 999333
> name Tom/26
> sex male
> phone 444999
> name Lisa/42
> sex female
> phone 222777
>
>
> any idea???
>
> Cheers

Re: Match a field and move data on the line above...

am 24.04.2008 15:08:47 von mop2

Yes, pure shell:

while read L;do
case "${L:0:1}" in n)n=$L;;a)echo $n/${L#* };;*)echo $L;esac
done