sed and the use of !


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting sed and the use of !
# 8  
Old 07-02-2013
Quote:
Originally Posted by steve54
Apologies Don, everyone,

"Bill:FredXX:Joe" -> "Bill:FredXX:Joe"

should have read

"Bill:FredXX:Joe" -> "Bill:Joe"

Don you are correct in that " fields that are separated by a colon and each line is terminated by a semicolon (followed by a <newline>)" but it may also be the case that some files are not terminated by a semicolon plus some files have in place of "field" (as above) have "field,value". So in this case the following is not true: "when you're searching for FRED6 , FRED61 should not be modified" i.e. it should be modified or rather removed as FRED61 is just another value. I don't like the way this is implemented, it would seem cleaner to me to have a file containing a list of fields to be removed and a script that operates on that file though this would be a harder script to create.

Don, sorry I don't get the code

printf '%s\n' "FRED6;"...etc

appears to print out everything regardless of whether sed is in place or not
You may notice that the last line of the printf statement ends with a |. The printf command is feeding sample data through a pipe into the sed command. It is just there to show that all occurrences of FRED6 and FRED6,string will be removed from the ouput if it appears at the start of a line followed by a colon or semicolon; from the end of a line followed by a semicolon (changing the preceding colon to a semicolon in this case) and from the middle of a line following and followed by other "names". It will NOT modify FRED61, or ALFRED6; only FRED6 and FRED6 immediately followed by a comma.

Changing my script to add an intermediate file and having sed read from that file involves the following huge changes: Take my original script:
Code:
printf '%s\n' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" \
        "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" \
        "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" \
        "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" \
        "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" |
        sed    '\!^FRED6\(,[^:]*\)\{0,1\};!d
                s!^FRED6\(,[^:]*\)\{0,1\}:!!
                s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                s!:FRED6\(,[^:]*\)\{0,1\};!;!'

and change it to:
Code:
printf '%s\n' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" \
        "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" \
        "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" \
        "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" \
        "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" > tmpfile
        sed    '\!^FRED6\(,[^:]*\)\{0,1\};!d
                s!^FRED6\(,[^:]*\)\{0,1\}:!!
                s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                s!:FRED6\(,[^:]*\)\{0,1\};!;!' tmpfile

Either way, the output produced is:
Code:
FRED61;
abc;
abc:FRED61;
abc;
abc:def;
abc:FRED61:def;
abc:def;
abc:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:GEORGE:def;
def;
FRED61:def;
def;
abc:No Changes to this:def;

All occurrences of FRED61 are untouched; all occurrences of FRED6 (as a name by itself and as a name followed by a comma and a string of non-colon characters following the comma have been removed from the output.

The sample data produced by the printf command is:
Code:
FRED6;
FRED61;
FRED6,45678;
abc:FRED6;
abc:FRED61;
abc:FRED6,45678;
abc:FRED6:def;
abc:FRED61:def;
abc:FRED6,45678:def;
abc:FRED6:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:FRED6,45678:GEORGE:def;
FRED6:def;
FRED61:def;
FRED6,45678:def;
abc:No Changes to this:def;

All of the data in red is removed by the sed script.

PS This script still assumes that lines are terminated by a semicolon as was shown in the earlier sample lines of input you provided, which were:
Code:
ONE:TWO:THREE:BERT:FOUR:FIVE;
ONE,1:TWO,2:THREE,3:BERT,999:FOUR,:FIVE,5;

If it is important to handle lines that don't end in a semicolon, I need to know whether (missing) semicolons should be added to the ends of lines that don't have them.

Last edited by Don Cragun; 07-02-2013 at 05:17 AM.. Reason: Add postscript about trailing semicolons.
# 9  
Old 07-02-2013
Hi Don,
Don't know if its I'm running on Solaris but i get a different o/p. Heres xterm with commands pasted in and run.

Code:
% printf '%s\n' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" \
>         "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" \
>         "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" \
>         "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" \
>         "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" |
pipe>         sed    '\!^FRED6\(,[^:]*\)\{0,1\};!d
pipe quote>                 s!^FRED6\(,[^:]*\)\{0,1\}:!!
pipe quote>                 s!:FRED6\(,[^:]*\)\{0,1\}:!:!
pipe quote>                 s!:FRED6\(,[^:]*\)\{0,1\};!;!'

' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" | sed '\!^FRED6\(,[^:]*\)\{0,1\};!d
                s!^FRED6\(,[^:]*\)\{0,1\}:!!
                s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                s!:FRED6\(,[^:]*\)\{0,1\};!;!' 
FRED6;
FRED61;
FRED6,45678;
abc:FRED6;
abc:FRED61;
abc:FRED6,45678;
abc:FRED6:def;
abc:FRED61:def;
abc:FRED6,45678:def;
abc:FRED6:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:FRED6,45678:GEORGE:def;
FRED6:def;
FRED61:def;
FRED6,45678:def;
abc:No Changes to this:def;

===========================================================


Code:
% printf '%s\n' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" \
>         "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" \
>         "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" \
>         "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" \
>         "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" > tmpfile

' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" > tmpfile msgmedia@AH-IN-UMF13:/home/msgmedia/stevebzsh: file exists: tmpfile
AH-IN-UMF13{msgmedia}568%         sed    '\!^FRED6\(,[^:]*\)\{0,1\};!d
quote>                 s!^FRED6\(,[^:]*\)\{0,1\}:!!
quote>                 s!:FRED6\(,[^:]*\)\{0,1\}:!:!
quote>                 s!:FRED6\(,[^:]*\)\{0,1\};!;!' tmpfile

                s!^FRED6\(,[^:]*\)\{0,1\}:!!
                s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                s!:FRED6\(,[^:]*\)\{0,1\};!;!' 
FRED6;
FRED61;
FRED6,45678;
abc:FRED6;
abc:FRED61;
abc:FRED6,45678;
abc:FRED6:def;
abc:FRED61:def;
abc:FRED6,45678:def;
abc:FRED6:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:FRED6,45678:GEORGE:def;
FRED6:def;
FRED61:def;
FRED6,45678:def;
abc:No Changes to this:def;

===========================================================
Run just the sed against the tmpfile

Code:
%  sed    '\!^FRED6\(,[^:]*\)\{0,1\};!d
quote>                 s!^FRED6\(,[^:]*\)\{0,1\}:!!
quote>                 s!:FRED6\(,[^:]*\)\{0,1\}:!:!
quote>                 s!:FRED6\(,[^:]*\)\{0,1\};!;!' tmpfile

                s!^FRED6\(,[^:]*\)\{0,1\}:!!
                s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                s!:FRED6\(,[^:]*\)\{0,1\};!;!' 
FRED6;
FRED61;
FRED6,45678;
abc:FRED6;
abc:FRED61;
abc:FRED6,45678;
abc:FRED6:def;
abc:FRED61:def;
abc:FRED6,45678:def;
abc:FRED6:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:FRED6,45678:GEORGE:def;
FRED6:def;
FRED61:def;
FRED6,45678:def;
abc:No Changes to this:def;

As for the files, format is either
Code:
1. X:Y:Z

or
Code:
2 X,value1:Y,value2:Z,value3;


Last edited by radoulov; 07-02-2013 at 08:22 AM..
# 10  
Old 07-02-2013
There is nothing in the sed command I provided that shouldn't work on any system that provides a sed that meets POSIX requirements. The output I showed you was from tests I ran on OS X on a MacBook Pro laptop. While digging around this morning, I found a note in the Linux sed(1) man page:
Quote:
POSIX.2 BREs should be supported, but they aren't completely because of performance problems.
So, if you are using a Linux system, that might be the problem.

What does the command:
Code:
uname -a

print on your system?

What shell are you using? If you don't know, show us the output from the command:
Code:
echo "$SHELL : $shell"

You didn't answer my question about trailing semicolons in your input: If a line in your input does not end with a semicolon, do you want this script to add one?

In your last post, you said:
Quote:
As for the files, format is either
Code:
1. X:Y:Z
    or
2 X,value1:Y,value2:Z,value3;

Does that mean that ,value only appears on lines that end with a semicolon and that every field in a line that ends with a semicolon will have a ,value on every field in that line???

Using metanotation where everything between [ and ] is optional and where [stuff]... means that the optional stuff can appear zero or more times, is the following an accurate representation of your input file format requirements?:
Code:
name[,value][:name[,value]]...[;]

where each occurrence of name is a string of one or more characters that are not colon, comma, or semicolon; and each occurrence of value is a string of zero or more characters that are neither colon nor semicolon?

Last edited by Don Cragun; 07-02-2013 at 04:05 PM.. Reason: Remove extra end CODE tag
# 11  
Old 07-03-2013
No not Linux, using /bin/zsh on a Sun box uname -irs = SunOS 5.10 SUNW,Netra-T5220. Really do not understand why there should be a problem with this box:
printf '%s\n' "FRED6;" | sed '\!^FRED6\(,[^:]*\)\{0,1\};!d'
echo "FRED6;" | sed '\!^FRED6\(,[^:]*\)\{0,1\};!d'

all print FRED6;

Yes to = "Does that mean that ,value only appears on lines that end with a semicolon and that every field in a line that ends with a semicolon will have a ,value on every field in that line"

Nothing is to be added to the files - it's a straightforward removal of a variable, and its value if it has one. It looks like - thanks to your help - the script should work but I really don't like the use of wildcards and think using a file with a list of all the variables to be removed would be safer.
# 12  
Old 07-03-2013
Do you get the same results if you specify /usr/xpg4/bin/sed instead of just sed in the script?

Many Solaris systems have the GNU utilities loaded into a directory and on those systems some users set their command search path to pick up the GNU utilities in preference to the "standard" utilities. What output do you get from the command line:
Code:
type sed;sed --version

# 13  
Old 07-04-2013
Absolutely amazing I'd no idea of this, you are absolutely correct, using /usr/xpg4/bin/sed in place of sed (which gives /bin/sed) works (btw also interesting there is no sed -version so seems you id what you are using...comes with the os maybe) :-

Code:
% printf '%s\n' "FRED6;" "FRED61;" "FRED6,45678;" "abc:FRED6;" "abc:FRED61;" \
         "abc:FRED6,45678;" "abc:FRED6:def;" "abc:FRED61:def;" \
         "abc:FRED6,45678:def;" "abc:FRED6:GEORGE:def;" \
         "abc:FRED61:GEORGE:def;" "abc:FRED6,45678:GEORGE:def;" "FRED6:def;" \
         "FRED61:def;" "FRED6,45678:def;" "abc:No Changes to this:def;" | /usr/xpg4/bin/sed    '
                 !^FRED6\(,[^:]*\)\{0,1\};!d
                 s!^FRED6\(,[^:]*\)\{0,1\}:!!
                 s!:FRED6\(,[^:]*\)\{0,1\}:!:!
                 s!:FRED6\(,[^:]*\)\{0,1\};!;!' > tmpfile

Code:
% cat tmpfile
FRED61;
abc;
abc:FRED61;
abc;
abc:def;
abc:FRED61:def;
abc:def;
abc:GEORGE:def;
abc:FRED61:GEORGE:def;
abc:GEORGE:def;
def;
FRED61:def;
def;
abc:No Changes to this:def;
%

Moderator's Comments:
Mod Comment Please use CODE tags.

Last edited by Don Cragun; 07-04-2013 at 04:56 PM.. Reason: Add CODE tags
# 14  
Old 07-04-2013
I'm glad to hear that you got it to work.

If your "default" sed had been a GNU version of sed, sed --version would have printed version information for that implementation of sed instead of a diagnostic saying it didn't know what --version meant. Since you are using Solaris 10 sed utilities, the command:
Code:
what /usr/bin/sed /usr/xpg4/bin/sed

will probably show you SCCS version information for those two sed utilities. (Some sys admins strip this information when installing Solaris systems to save a little disk space.)
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

I am learning regular expression in sed,Please help me understand the use curly bracket in sed,

I am learning SED and just following the shell scripting book, i have trouble understanding the grep and sed statement, Question : 1 __________ /opt/oracle/work/antony>cat teledir.txt jai sharma 25853670 chanchal singhvi 9831545629 anil aggarwal 9830263298 shyam saksena 23217847 lalit... (7 Replies)
Discussion started by: Antony Ankrose
7 Replies

2. Shell Programming and Scripting

sed and awk giving error ./sample.sh: line 13: sed: command not found

Hi, I am running a script sample.sh in bash environment .In the script i am using sed and awk commands which when executed individually from terminal they are getting executed normally but when i give these sed and awk commands in the script it is giving the below errors :- ./sample.sh: line... (12 Replies)
Discussion started by: satishmallidi
12 Replies

3. Shell Programming and Scripting

sed inside sed for replacing string

My need is : Want to change docBase="/something/something/something" to docBase="/only/this/path/for/all/files" I have some (about 250 files)xml files. In FileOne it contains <Context path="/PPP" displayName="PPP" docBase="/home/me/documents" reloadable="true" crossContext="true">... (1 Reply)
Discussion started by: linuxadmin
1 Replies

4. Shell Programming and Scripting

How to use sed to replace the a string in the same file using sed?

How do i replace a string using sed into the same file without creating a intermediate file? (7 Replies)
Discussion started by: gomes1333
7 Replies

5. UNIX for Dummies Questions & Answers

SED: Can't Repeat Search Character in SED Output

I'm not sure if the problem I'm seeing is an artifact of sed or simply a beginner's mistake. Here's the problem: I want to add a zero-width space following each underscore between XML tags. For example, if I had the following xml: <MY_BIG_TAG>This_is_a_test</MY_BIG_TAG> It should look like... (8 Replies)
Discussion started by: rhetoric101
8 Replies

6. Shell Programming and Scripting

deleting text records with sed (sed paragraphs)

Hi all, First off, Thank you all for the knowledge I have gleaned from this site! Deleting Records from a text file... sed paragraphs The following code works nearly perfect, however each time it is run on the log file it adds a newline at the head of the file, run it 5 times, it'll have 5... (1 Reply)
Discussion started by: Festus Hagen
1 Replies

7. Shell Programming and Scripting

sed has zeored my files. Help me with sed please

i made a script to update a lot of xml files. to save me some time. Ran it and it replaced all the the files with a 0kb file. The problem i was having is that I am using sed to change xml node <doc_root>. The problem with this is it has a / in the closing xml tag and the stuff inside will also have... (4 Replies)
Discussion started by: timgolding
4 Replies

8. Shell Programming and Scripting

sed over writes my original file (using sed to remove leading spaces)

Hello and thx for reading this I'm using sed to remove only the leading spaces in a file bash-280R# cat foofile some text some text some text some text some text bash-280R# bash-280R# sed 's/^ *//' foofile > foofile.use bash-280R# cat foofile.use some text some text some text... (6 Replies)
Discussion started by: laser
6 Replies

9. Shell Programming and Scripting

Issue with a sed one liner variant - sed 's/ ; /|/g' $TMP1 > $TMP

Execution of the following segment is giving the error - Script extract:- OUT=$DATADIR/sol_rsult_orphn.bcp TMP1=${OUT}_tmp1 TMP=${OUT}_tmp ( isql -w 400 $dbConnect_OPR <<EOF select convert(char(10), s.lead_id) +'|' + s.pho_loc_type, ";", s.sol_rsult_cmnt, ";", +'|'+ s.del_ind... (3 Replies)
Discussion started by: kzmatam
3 Replies

10. Shell Programming and Scripting

Sed Question 1. (Don't quite know how to use sed! Thanks)

Write a sed script to extract the year, rank, and stock for the most recent 10 years available in the file top10_mktval.csv, and output in the following format: ------------------------------ YEAR |RANK| STOCK ------------------------------ 2007 | 1 | Exxon... (1 Reply)
Discussion started by: beibeiatNY
1 Replies
Login or Register to Ask a Question