[sed] Replace one line with two lines


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting [sed] Replace one line with two lines
# 1  
[sed] Replace one line with two lines

Literally cannot get this one, guys. Single line replacement is simple, but I am not understanding the correct syntax for including a new line feed into the substitution part.

Here's what I got. (Cannot use perl)

Code:
#!/bin/sh
set -f
#Start Perms
export HOME=/home/test_user
# End Perms

# Replace ./x.mak with these two lines
#     chmod 775 x.mak
#     ./x.mak
find . -type -f print0 |xargs sed 's|./x.mak|chmod 775 x.mak \ ./x.mak|g'
# Done

It renders a terminating error. I'm looking for the correct syntax to basically prepend the chmod part before the search pattern, but just by replacing it, as I've tried a few different ways to try to prepend it, but it didn't work.
# 2  
A couple of things...

First, you should escape the dot in your pattern so that something like y/x.mak doesn't also match. It might not be a probability in your current directory structure, but these are the kinds of things that can come back to cause odd problems later.

Second, you should be able to use a \n to add a newline in the replacement:

Code:
sed  's|\./x.mak|chmod 775 x.mak\n./x.mak|g'


Last edited by agama; 05-28-2013 at 11:35 PM.. Reason: small grammar fix
# 3  
The dot pattern is because it's being executed, but it doesn't have the perms to do so yet, which is why I'm trying to prepend chmod before executing it
# 4  
Quote:
Originally Posted by Parallax
The dot pattern is because it's being executed, but it doesn't have the perms to do so yet, which is why I'm trying to prepend chmod before executing it
Understood. What I was indicating was that if the subdirectory foo/x.mak exists it will be matched if ./x.mak is used where if \./x.mak is used it will not.

I guess actually both dots in the pattern should be escaped for correctness:

Code:
s|\./x\.mak|chmod 775 x.mak\n./x.mak|g

# 5  
There are a few problems here. If this script is in the directory where you are looking for and changing occurrences of "./x.mak", one of the files it will try to modify is itself (in at least two places).

Second, in standards conforming versions of sed, \n in the replacement string of a substitute command will insert an <n> character, not a <newline> character. I know that some versions of sed do provide the common backslash escapes here, but using them here might or might not work depending on what OS (or sed utility) you're using. In a standards conforming sed, you could use a backslash-escaped literal newline character instead of the \n to get what you want:
Code:
sed  's|\./x\.mak|chmod 775 x.mak\
./x.mak|g'

Third, the -print0 primary in find is also an extension to the standards. If the system you're using supports it and you're going to use xargs as well as find -print0 you have to also use the xargs -0 option when you invoke xargs. If you wanted a more portable way to do this you could try:
Code:
find . -type -f -exec sed  's|\./x\.mak|chmod 775 x.mak\
./x.mak|g' {} \;

And finally, the script you provided seems to try to print the contents of all of the regular files it finds in and under the current directory (with changes to any occurrence of "./x.mak") to standard output, but does not save any of the changes into any of the source files. I would guess this isn't what you're trying to do. Smilie (If this really is what you want, you could also change the \; at the end of the find -exec primary's arguments in the last suggestion above to + to run more efficiently.)

If you do want to actually change the contents of the files containing "./x.mak" (and only them), you are absolutely certain that no filename components in the file hierarchy you'll be processing contain a <newline> character, and you only want to change files in the current directory or a known list of directories (not those in all subdirectories recursively); you might consider a loop like:
Code:
grep -Fl ./x.mak * other_directory/* ... |while IFS="" read -r file
do      process "$file"
done

where I would expect processing would exclude your script and actually change the contents of other files that contained the target string. Note that grep -F matches fixed strings (not regular expressions) so the periods don't need to be escaped here. (Note also that some versions of grep provide a recursive option (-R) that could be used as:
Code:
grep -FlR ./x.mak .|while IFS="" read -r file
do      process "$file"
done

to process all files in and under the current directory containing the target string.)

Hope this helps.
This User Gave Thanks to Don Cragun For This Post:
# 6  
So if I wanted to replace the occurrences recursively, is that impossible? Was wrong in thinking find and sed could do this?
# 7  
Quote:
Originally Posted by Parallax
So if I wanted to replace the occurrences recursively, is that impossible? Was wrong in thinking find and sed could do this?
I don't understand what you're trying to do. Applying your changes to a file recursively would change the following line in a file:
Code:
#       ./x.mak

to:
Code:
#       chmod 755 x.mak
chmod 755 x.mak
chmod 755 x.mak
...
./x.mak

with the "..." replaced by enough copies of "chmod 755 x.mak" to fill up your file system or exceed a file size limit for the file you're modifying.

Find and sed or the shell can modify a file in an infinite number of ways; but the code you showed us doesn't actually make any changes to any file; it just displays modified versions of a potentially huge number of file without saving modifications to any of them.

Please tell us in English exactly what you're trying to do with sample input and desired output. Showing us code that isn't doing what you want to do and making us guess at what you do want to do is not likely to produce working code.

If you're trying something and it is printing an error message, SHOW US THE EXACT ERROR MESSAGE(S).

Tell us what system you're using and what shell you use. Different Linux and UNIX operating systems provide different utilities and different options for common utilities. The shell you use (if we aren't allowed to choose the shell) may greatly limit the choices we have to provide working code.
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #893
Difficulty: Easy
sed uses regular expressions, such as .* (zero or more of any character).
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Replace values in script reading line by line using sed

Hi all, Let's say I have a script calling for the two variables PA_VALUE and PB_VALUE. for pa in PA_VALUE blah blah do for pb in PB_VALUE blah blah do I have a text file with two columns of values for PA and PB. 14.5 16.7 7.8 9.5 5.6 3.6 etc etc I would like to read this... (7 Replies)
Discussion started by: crimsonengineer
7 Replies

2. Shell Programming and Scripting

sed command to replace a line in a file using line number from the output of a pipe.

Sed command to replace a line in a file using line number from the output of a pipe. Is it possible to replace a whole line piped from someother command into a file at paritcular line... here is some basic execution flow.. the line number is 412 lineNo=412 Now i have a line... (1 Reply)
Discussion started by: vivek d r
1 Replies

3. Shell Programming and Scripting

Multiple line search, replace second line, using awk or sed

All, I appreciate any help you can offer here as this is well beyond my grasp of awk/sed... I have an input file similar to: &LOG &LOG Part: "@DB/TC10000021855/--F" &LOG &LOG &LOG Part: "@DB/TC10000021852/--F" &LOG Cloning_Action: RETAIN &LOG Part: "@DB/TCCP000010713/--A" &LOG &LOG... (5 Replies)
Discussion started by: KarmaPoliceT2
5 Replies

4. Shell Programming and Scripting

sed command to replace a line at a specific line number with some other line

my requirement is, consider a file output cat output blah sdjfhjkd jsdfhjksdh sdfs 23423 sdfsdf sdf"sdfsdf"sdfsdf"""""dsf hellow there this doesnt look good et cetc etc etcetera i want to replace a line of line number 4 ("this doesnt look good") with some other line ... (3 Replies)
Discussion started by: vivek d r
3 Replies

5. Shell Programming and Scripting

I need to know how to replace a line after a pattern match with an empty line using SED

Hi How Are you? I am doing fine! I need to go now? I will see you tomorrow! Basically I need to replace the entire line containing "doing" with a blank line: I need to the following output: Hi How Are you? I need to go now? I will see you tomorrow! Thanks in advance.... (1 Reply)
Discussion started by: sags007_99
1 Replies

6. Shell Programming and Scripting

sed to replace a line with multi lines from a var

I am trying to find a line in a file ("Replace_Flag") and replace it with a variable which hold a multi lined file. myVar=`cat myfile` sed -e 's/Replace_Flag/'$myVar'/' /pathto/test.file myfile: cat dog boy girl mouse house test.file: football hockey Replace_Flag baseball ... (4 Replies)
Discussion started by: bblondin
4 Replies

7. Shell Programming and Scripting

sed to replace a line with 2 or more different lines in same file

i have something like this... cat filename.txt <complexType name="abc"> bklah vlah blah blha blha blah blha </complexType > <complexType name="def"> bklah vlah blah blha blha blah blha </complexType > . . .and so on.. its a very large file (11 Replies)
Discussion started by: vivek d r
11 Replies

8. Shell Programming and Scripting

replace (sed?) a single line/string in file with multiple lines (string) from another file??

Can someone tell me how I can do this? e.g: Say file1.txt contains: today is monday the 22 of NOVEMBER 2010 and file2.txt contains: the 11th month of How do i replace the word NOVEMBER with (5 Replies)
Discussion started by: tuathan
5 Replies

9. Shell Programming and Scripting

sed to replace two lines with one

I want to use sed to check if a short line is contained in the line after it, and if it is, to delete the short one. In other words, the input is... This is a This is a line ... and I want it to give me... This is a line Here's what I've tried so far: s/\(^.*\)\n\(\1.*$\)/\2/ Also,... (7 Replies)
Discussion started by: estebandido
7 Replies

10. Shell Programming and Scripting

sed - Replace Line which contains the Pattern match with a new line

I need to replace the line containing "STAGE_DB" with the line "STAGE_DB $DB # database that contains the table being loaded ($workingDB)" Here $DB is passed during the runtime. How can I do this? Thanks, Kousikan (2 Replies)
Discussion started by: kousikan
2 Replies

Featured Tech Videos