LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-22-2012, 12:37 PM   #1
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,733

Rep: Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591
sed - using variable values as patterns


This is purely a learning exercise.
I have no real-world application.

I have a file of names in the format FirstName LastName.
I want to exchange the two fields to produce a new file
containing the same information in the format LastName FirstName.

This works ...
Code:
sed 's/\([[:graph:]]*\) \([[:graph:]]*\)/\2 \1/'
As an experiment I tried to specify the patterns as variables.
Code:
Word=' \([[:graph:]]*\) '
sed 's/' $Word $Word '/\2 \1/'
This fails with ...
Quote:
sed: -e expression #1, char 2: unterminated `s' command
Please advise.

Daniel B. Martin
 
Old 01-22-2012, 01:01 PM   #2
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by danielbmartin View Post
Code:
Word=' \([[:graph:]]*\) '
sed 's/' $Word $Word '/\2 \1/'
There are spaces in the argument to sed, therefore sed recieves the expression as 4 separate arguments. You should remove the spaces or quote them or use double quotes:
Code:
sed 's/'$Word$Word'/\2 \1/'
sed 's/ '$Word' '$Word' /\2 \1/'
sed 's/'" $Word $Word "'/\2 \1/'
or something along those lines
 
1 members found this post helpful.
Old 01-22-2012, 08:52 PM   #3
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,733

Original Poster
Rep: Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591
Quote:
Originally Posted by millgates View Post
There are spaces in the argument to sed, therefore sed recieves the expression as 4 separate arguments. You should remove the spaces or quote them or use double quotes:
Code:
sed 's/'$Word$Word'/\2 \1/'
sed 's/ '$Word' '$Word' /\2 \1/'
sed 's/'" $Word $Word "'/\2 \1/'
or something along those lines
Thank you, millgates, for your timely and informative response. I removed the leading and trailing blanks from the variable Word.
Code:
Word='\([[:graph:]]*\)'
Having done this, all three of your sed examples work. However, the first of the three puts a leading blank on each line and I don't understand why that happens.

Daniel B. Martin
 
Old 01-23-2012, 01:05 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,723

Rep: Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035Reputation: 3035
How about just use double quotes:
Code:
sed "s/$Word$Word/\2 \1/"
 
Old 01-23-2012, 11:23 AM   #5
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,733

Original Poster
Rep: Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591
Whoa! I took a closer look at the suggested solutions and
they don't work (unlikely), or
I've implemented them incorrectly.

Here's some simple code. Try it yourself and tell me how I goofed it!

Code:
echo; echo The input file is...
cat < $InFile
 
echo; echo Example 1...
sed 's/\([[:graph:]]*\) \([[:graph:]]*\)/\2 \1/' $InFile

Word='\([[:graph:]]*\)'

echo; echo Example 2...
sed 's/'$Word$Word'/\2 \1/' $InFile

echo; echo Example 3...
sed 's/ '$Word' '$Word' /\2 \1/' $InFile
 
echo; echo Example 4...
sed 's/'" $Word $Word "'/\2 \1/' $InFile

echo; echo Example 5...
sed "s/$Word$Word/\2 \1/" $InFile  
echo; echo
Here is the output from running that code.
Code:
The input file is...
Charles Curtis
John Garner
Henry Wallace
Alben Barkley

Example 1...
Curtis Charles
Garner John
Wallace Henry
Barkley Alben

Example 2...
 Charles Curtis
 John Garner
 Henry Wallace
 Alben Barkley

Example 3...
Charles Curtis
John Garner
Henry Wallace
Alben Barkley

Example 4...
Charles Curtis
John Garner
Henry Wallace
Alben Barkley

Example 5...
 Charles Curtis
 John Garner
 Henry Wallace
 Alben Barkley
Daniel B. Martin
 
Old 01-23-2012, 11:46 AM   #6
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

5th example should look like this
Code:
$ Word='\([[:graph:]]*\)'
$ echo a b | sed "s/$Word $Word/\2 \1/"
b a
Note the space between two $Word's. Without the space you would get
Code:
$ echo a b | sed "s/$Word$Word/[\2] {\1}/"
[] {a} b
Space do not belong to the [:graph:] character class, so the first group matches only `a' and the second one matches empty string. IMO using double quotes (") is a preferred way to do such task.
 
1 members found this post helpful.
Old 01-23-2012, 12:08 PM   #7
jthill
Member
 
Registered: Mar 2010
Distribution: Arch
Posts: 211

Rep: Reputation: 67
You might find the following program helpful:
Code:
~/sandbox/49381$ cat >showargs.c
#include <stdio.h>
void main (int c, char **v, char **e)
{
        while (*v) puts(*v++);
        while (*e) puts(*e++);
}
~/sandbox/49381$ make showargs
cc     showargs.c   -o showargs
~/sandbox/49381$ ./showargs *
./showargs
UIDvsSID
a
a.cc
b
b.cc
declorder.cc
duff.cc
duff.o
opendir
opendir.cc
opendir2
opendir2.cc
sanitize
showargs
showargs.c
size
size.c
tags
SHELL=/bin/bash
TERM=xterm
XDG_SESSION_COOKIE=03b561d92e2a1484d958eade00000009-1327249405.440338-1264992931
TMPDIR=/tmp/jthill
WINDOWID=6291469
HUSHLOGIN=FALSE
XTERM_SHELL=/bin/bash
USER=jthill
   (and the rest of the environment variables...)
and you can pipe the result through 'sed -n l' or 'cat -A' if spacing or the like is a concern.
 
Old 01-23-2012, 03:20 PM   #8
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,733

Original Poster
Rep: Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591Reputation: 591
Quote:
Originally Posted by firstfire View Post
5th example should look like this
Code:
$ Word='\([[:graph:]]*\)'
$ echo a b | sed "s/$Word $Word/\2 \1/"
b a
Note the space between two $Word's.
You are right. Example 5 now works correctly. Thank you!

Daniel B. Martin
 
  


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
sed to change patterns on multiple lines neuroimager Linux - General 4 12-08-2010 12:02 PM
Sed. Delete blank lines between two patterns supersoni3 Programming 5 07-29-2010 11:40 AM
sed replacing patterns with back quoted command rattlesnakejoe Programming 2 11-18-2009 10:12 AM
SED how to find multiple patterns on a single line yaazz Programming 9 07-31-2009 05:20 AM
Remembering patterns and printing only those patterns using sed bernie82 Programming 5 05-26-2005 06:18 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:31 PM.

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