LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-22-2012, 02:36 PM   #1
upendra_35
LQ Newbie
 
Registered: Oct 2012
Posts: 21

Rep: Reputation: Disabled
'sed' or 'awk' help


Hi,

I would like to do the following. Please help me doing this either with awk or sed.

Code:
CUFF.8.1 => CUFF.8_seq1
CUFF.9.1 => CUFF.9_seq1
CUFF.8.2 => CUFF.8_seq2
So basically what all i want to do is convert .1 into _seq1 and all .2 into _seq2 and so on. I know how to use sed but when i do the below it subsitutes the first "." but not the second "."

PHP Code:
sed  's/.1/_seq1/' 
 
Old 10-22-2012, 02:55 PM   #2
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2 on Lenovo Thinkpad W520
Posts: 7,454

Rep: Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411
Code:
sed 's/.1/_seq1/g'
 
Old 10-22-2012, 02:58 PM   #3
upendra_35
LQ Newbie
 
Registered: Oct 2012
Posts: 21

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by Didier Spaier View Post
Code:
sed 's/.1/_seq1/g'
When I add 'g' it does substitute at both positions. I guess 'g' is for global right?

CUFF_seq1_seq1

Last edited by upendra_35; 10-22-2012 at 03:13 PM.
 
Old 10-22-2012, 04:03 PM   #4
Didier Spaier
LQ Addict
 
Registered: Nov 2008
Location: Paris, France
Distribution: Slint64-14.2 on Lenovo Thinkpad W520
Posts: 7,454

Rep: Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411Reputation: 2411
Right.
 
Old 10-22-2012, 04:07 PM   #5
sycamorex
LQ Veteran
 
Registered: Nov 2005
Location: London
Distribution: Slackware64-current
Posts: 5,819
Blog Entries: 1

Rep: Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209Reputation: 1209
Edit: sorry - I forgot about the dot.

If I understand you correctly and all the numbers are 1-digit numbers, this should cover all your cases:

Code:
sed 's/[0-9]/_seq&/g' file

Last edited by sycamorex; 10-22-2012 at 04:11 PM.
 
Old 10-22-2012, 04:08 PM   #6
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 840

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
Hi, what about
Code:
sed 's/\(.*\)\./\1_seq/'
 
Old 10-22-2012, 10:34 PM   #7
upendra_35
LQ Newbie
 
Registered: Oct 2012
Posts: 21

Original Poster
Rep: Reputation: Disabled
Thumbs up

Quote:
Originally Posted by millgates View Post
Hi, what about
Code:
sed 's/\(.*\)\./\1_seq/'
This is exactly what i wanted. Thanks for your help.

Upendra
 
Old 10-23-2012, 03:02 AM   #8
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
First, understand that "." has a special meaning in regular expressions. It stands for "any character". So '.1' will match any single character followed by a one, i.e. 'a1', ',1', ' 1', etc.

To make it literal you have to either backslash escape it or enclose it in [] brackets.

Second, in sed's 's///' substitution expression, the entire left side match is replaced by the right side string. So if you want to carry over any values you have to use regex backreference capturing.


millgates' reply shows one working version, although I would give it a more precise matching expression. His version just matches everything from the beginning of the line up to the first literal period. If the line contained a period before the one you wanted, it would insert the _seq in the wrong place.

I would also add one more thing. It's a gnu extension that allows you to enable extended regex features through backslashing. A cleaner and more readable way to get the same effect is to use the -r option, and just enable ext-re globally.

Code:
sed -r 's/(CUFF[.][0-9])[.]([0-9])/\1_seq\2/'
Add a 'g' to the end if more than one string can exist on a single line, as mentioned.

See the grep man page for a good explanation of basic vs. extended regular expressions. And when you have a chance, take some time to study up on regex in general. You'll be glad you did.

Here are a few regular expressions tutorials:
http://mywiki.wooledge.org/RegularExpression
http://www.grymoire.com/Unix/Regular.html
http://www.regular-expressions.info/
 
Old 10-23-2012, 03:09 AM   #9
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 840

Rep: Reputation: 380Reputation: 380Reputation: 380Reputation: 380
Quote:
Originally Posted by David the H. View Post
millgates' reply shows one working version, although I would give it a more precise matching expression. His version just matches everything from the beginning of the line up to the first literal period. If the line contained a period before the one you wanted, it would insert the _seq in the wrong place.
Actually, it matches everything up to the last period, since the .* is greedy. But I agree it deserves a better matching expression.
 
Old 10-23-2012, 03:10 AM   #10
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959Reputation: 1959
Oh, by the way, if we can guarantee that there are no other numbers on each line before the pattern that you want, the expression can be made much easier.

Code:
sed 's/[0-9]/_seq&/2'
'&' can be used in the RHS to mean the entire LHS match, and a little-documented feature of sed allows you to specify exactly which instance on the line to substitute. So we just tell it to match and replace the second number found on the line.

Edit @millgates: Thanks for the correction. I guess I'm not thinking too clearly right now.

Edit again: Actually, scratch my substitution above. I forgot we have to remove the period as well. Can't do that with a simple match.

Last edited by David the H.; 10-23-2012 at 03:14 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with awk or sed. tuxtutorials Linux - Software 3 07-23-2009 03:26 PM
Help with awk or sed. tuxtutorials Linux - Software 1 07-23-2009 02:45 AM
sed or awk ilo Programming 1 08-22-2008 10:38 AM
awk or sed help cmontr Programming 16 05-14-2008 10:59 AM
awk/sed help pantera Programming 1 05-13-2004 11:59 PM


All times are GMT -5. The time now is 02:47 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration