Print character after pattern found

Hi Gurus, i need your help to create a script the will print a characters after the pattern was found.
Sample lines are below:

My birthday:"1977-16-07", My birthday:"1975-16-07"
My birthday:"1970-16-07"

.

My patter should be "birthday:", then i want to print the following characters which is the complete date: Note( some lines has multiple occurence of the patters)
So my desired output would be:

1977-16-07
1975-16-07
1970-16-07

appreciate your help. Thanks

Perl way...there are many ways to do it with awk and grep as well...

$ perl -nle '$,="\n";@array = /birthday:\"(\d{4,4}-\d{2,2}-\d{2,2})\"/g; print @array' file
1977-16-07
1975-16-07
1970-16-07

please provide some back ground information.Seems the query is not pretty clear to create a script.there can be multiple ways to do as per above statements but not yet clear what is the specific requirement

you can try with awk and regex.

In your sample, the pattern doesn't matter, and your statement specifying your requirements doesn't match the output you say you want (the double quotes are missing in the output).

To get the output you requested from the input you gave (if I guessed correctly about where the CODE tags should have been), you could try something simple like:

awk -F'"' '{for(i = 2; i < NF; i += 2) print $i}' file

If file contains your sample input, the output produced matches your desired output.

As always, if you're using a Solaris/SunOS system, you need to use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of /bin/awk or /usr/bin/awk .

Thanks.. Can you show me how it is done in awk and grep? Thanks a lot

scripter123,

Check this out:

awk '{A=split($0,a,/"/);for(i=1;i<=A;i++) if(a~/birthday/) print a[i+1]}' file
1977-16-07
1975-16-07
1970-16-07

Enjoy ,Have fun!.

Thanks.
I think i would need to give the exact sample of the content.

See below:

my birthday="1977-15-07L5093" my birthday="1967-15-07L5678"
my birthday="1970-15-07L5093"

My desired output is the Date e.g. 1977-15-07 which is the next 10 characters after (birthday=").
For the above sample line, i should have the below output:

1977-15-07
1967-15-07
1970-15-07

---------- Post updated at 03:29 AM ---------- Previous update was at 12:54 AM ----------

Hi Don, Sorry for the confusion:
I think i would need to give you the exact sample of the file content.

See below:

my birthday="1977-15-07L5093" my birthday="1967-15-07L5678"
my birthday="1970-15-07L5093"

My desired output is the Date e.g. 1977-15-07 which is the next 10 characters after (birthday=").
For the above sample line, i should have the below output:

1977-15-07
1967-15-07
1970-15-07

Appreciate your help on this. Thanks

With your new requirements and new sample input, there is still no need to look for birthday=". The following simple awk script produces your new required output with your new exact sample:

awk -F'"' '{for(i = 2; i < NF; i += 2) print substr($i, 1, 10)}' file

What we really need is not an exact sample, but an exact specification of what is allowed in the input this program is supposed to process. But, giving us samples that are not representative of your input just wastes your time and ours.

>> But, giving us samples that are not representative of your input just wastes your time and ours.

  • I Totaly agree with Don. Scripter123 please note it down before posting next time, to have correct sample in first place.

apologies gentlemen.

And I guess that the real life data is more than 2 lines.
Also in post #1 its used , to separat fileds, this is gone in next example

Hi Don, Thanks, the command works well and apologies on the previous confusion.

I have a follow query on how would i put into a variable the return dates.
print substr($i, 1, 10) - as what i understand, this line will print the return date, how would i put it in a variable?

Yes, the awk command:

print substr($i, 1, 10)

prints the up to 10 characters starting with the 1st character from field number i in the current input line.

What kind of variable? What do you want to do with this variable? You're being vague about what you want again!

Is this what you mean?

awk -F'"' '
{	for(i = 2; i < NF; i += 2) {
		d = substr($i, 1, 10)
		print d
	}
}' file

Is this what you mean?

awk -F'"' '
{	for(i = 2; i < NF; i += 2)
		d[++dc] = substr($i, 1, 10)
}
END {   for(i = 1; i <= dc; i++)
		print d
}' file

Both of the above shell scripts produce the same output as my previous awk command, but run slower. For "large" input files, the second one also takes more memory and for "HUGE" input files will eventually run out of memory.

Is this what you mean?

#!/bin/ksh
awk -F'"' '{for(i = 2; i < NF; i += 2) print substr($i, 1, 10)}' file |
while read d
do      echo $d
done

The above shell script will work with any POSIX conforming shell.

Is this what you mean?

#!/bin/ksh
d="$(awk -F'"' '{for(i = 2; i < NF; i += 2) print substr($i, 1, 10)}' file)"
echo $d | {
        read -A da
        i=0
        while [ $i -lt ${#da[@]} ]
        do      echo ${da[$i]}
                i=$((i + 1))
        done
}

The above shell script only works with 1993 and later versions of the Korn shell.

Is this what you mean?

#!/bin/bash
d="$(awk -F'"' '{for(i = 2; i < NF; i += 2) print substr($i, 1, 10)}' file)"
echo $d | {
        read -a da
        i=0
        while [ $i -lt ${#da[@]} ]
        do      echo ${da[$i]}
                i=$((i + 1))
        done
}

The above shell script only works with bash.

The last three shell scripts above all also produce the same output as my last awk command, but are slower yet. With sufficiently large input files, the last two could run into LINE_MAX, ARG_MAX, shell array size, and/or amount of memory available to the shell limitations.

Obviously there are thousands of other ways to assign output from a utility into variables into variables of various types in various programming languages. If you don't give us details about what you want, we can waste lots of time trying to guess what you want; or we can just ignore future requests for help from you.

Many people post vague questions like yours and the often get results. A few people post questions like:
I am using the WWW shell on XXX hardware running the YYY version of the ZZZ operating system. i have input files with the following input format: description of format
and here is a representative sample of an input file in this format:

input file name:

sample input

I want to produce output with the following characteristics: description of output
and here is the output I want to have produced from the input sample above:

output file name:

exact output desired for the given sample input

Here is what I have tried so far:

sample code

but it gives me the following errors or fails to produce the output that I want for reasons that I don't understand:

exact output from the above code when processing the sample input above

Can you help me correct my code, explain what I'm doing wrong, or tell me where to find an answer for my problem?

People who take the time and effort to start a thread with a post like that almost always get a quick, accurate, and working solution VERY quickly. And future posts from these people are naturally given a much higher priority by the volunteers in The UNIX and Linux Forum who try to help people asking questions.

Hi Don, Thanks for the response.
Basically print substr($i, 1, 10) will display a timestamp e.g. 2013-16-07 .
I want this timestamp to be assigned in a variable e.g. "x".
Then ill add 5 days using the below command:

date -d "$x 5 days" +%F

So, the third example I gave you is exactly what you want:

#!/bin/ksh
awk -F'"' '{for(i = 2; i < NF; i += 2) print substr($i, 1, 10)}' file |
while read d
do      date -d "$d + 5 days" +%F
done

I don't have a GNU date utility to play with and the Linux date man page is vague, but I think you need to add the plus sign that I marked in red above to get the dates 5 days after the given birthdays.

Thanks Don,
"date -d "$d 5 days" +%F" works so far in ubuntu. But i have another problem when executing the below commands:

while read d
do      
x=$(date -d "$d 5 days" +%F)
echo $x
sed 's/$d/$x/g' file > file2
done

I added "echo $x" just to see if its returning the correct output and yes, its displaying the correct one. But
the file2 content doesnt get updated with the correct date which is timestamp+5 days.

You need to use double quotes if you want the shell to expand variables within a string.

And, please, to preserve formatting, start using code tags for code and data. Moderators have already edited multiple posts of yours in this thread for that reason.

Regards,
Alister

Hi Alister,
Sorry. Ill take note of that code tags.
Thanks for the help Don. I got it resolved.