simple SED replace - regex

Just attempting to write a script to do a simple regex replace in php.ini, what I want to do is replace the line ;cgi.fix_pathinfo=1 with cgi.fix_pathinfo=0.
Ideally want to avoid installing any additional packages so sed seems a logical choice since it is bundled with FreeBSD. I have tried the following but doesn't seem to work:
sed 's/;cgi\.fix_pathinfo=1/cgi\.fix_pathinfo=0/' /usr/local/etc/php.ini

To change the content of a file in place with sed BSD, you can do that:
sed -i.bak -e 's/;cgi\.fix_pathinfo=1/cgi.fix_pathinfo=0/;' /usr/local/etc/php.ini
That creates a copy of the old file with a .bak extension.
Or without creating a copy:
sed -i '' -e 's/;cgi\.fix_pathinfo=1/cgi.fix_pathinfo=0/;' /usr/local/etc/php.ini
Note that in this case, a space and an empty string enclosed between quotes are mandatory. You can't simply write sed -i -e '... like with GNU sed.

Related

Remove new lines except when preceded by specific set of characters

How can I remove new lines using Perl and / or Sed at the bash command line but avoiding a specific set of characters?
The closest I came from this is:
perl -C -i -p -e 's/[^.:]\n//' ~/Desktop/bak2
The above code is working well on avoid removing lines ended with a dot or a colon, but its failling because when removing the correct new lines its also erasing the very last character of the string. I also would need the removed \n to be substituted by a space.
Would be great, if possible, to have this solution by Perl and also by Sed.
I've searched for a similar solution in perl or sed and I haven't found it,sorry if it does exists.
Examples:
Existing content:
Violets are blue and
Buda has great teachings.
Programming can be easy because:
Stackoverflow exists,
and the community always helps
a lot.
Desired output:
Violets are blue and Buda has great teachings.
Programming can be easy because:
Stackoverflow exists, and the community always helps a lot.
With sed
sed -e ':A;/[^.:]$/{N;bA' -e '};y/\n/ /' ~/Desktop/bak2
or gnu sed
sed -z 's/\([^.:]\)\n/\1 /g' ~/Desktop/bak2
You may preserve pre new-line match (I added "empty" lines handling):
perl -C -i -p -e 's/(^|[^.:])\n/$1/' ~/Desktop/bak2
or use positive look behind
perl -C -i -p -e 's/(?<=[^.:])\n//' ~/Desktop/bak2
perl -i pe 's/[^.:]\K\n/ /' ~/Desktop/bak2

sed command creating unwanted duplicates of file with -e extension

I am trying to do a recursive find and replace on java files in a directory using a shell script. It works, but it is hiding all the files, and creating duplicates with a -e extension
#!/bin/bash
for file in $(find . -type f -name "*.java")
do sed -i -e 's/foo/bar/g' $file
done
From my understanding, the -e is optional - but if I do not provide it I get the following error on every file it finds
sed: 1: "./DirectoryAdapter.java": invalid command code .
Any clue as it what is happening here? For reference I am on Mac OS X running El Capitan
Here is a before and after screenshot of the directory after running the script. The replaced files still exist, they are hidden?
On OSX sed (BSD) sed requires an extension after -i option. Since it is finding -e afterwards it is adding -e to each input filename. btw you don't even need -e option here.
You can pass an empty extension like this:
sed -i '' 's/foo/bar/g' $file
Or use .bak for an extension to save original file:
sed -i.bak 's/foo/bar/g' $file
The accepted answer works for OSX but causes issues if your code is run on both GNU and OSX systems since they expect -i[SUFFIX] and -i [SUFFIX] respectively.
There are probably two reasonable solutions in this case.
Don't use -i (inplace). Instead pipe to a temporary file and overwrite the original after.
use perl.
The easiest fix for this I found was to simply use perl. The syntax is almost identical:
sed -i -e 's/foo/bar/g' $file
->
perl -pi -e 's/foo/bar/g' $file

Using sed in Windows with simple regular expression in file path

I use a simple regular expression in file path when calling this sed command:
sed -i "s/showIntro.*/showIntro\t= false/" "c:\me\test_*\config.ini"
where * matches the suffix of a folder test_ in the path. (e.g. test_1.0, test_2.0, etc)
But for some reason the sed gives me an error:
sed: c:\me\test_*\config.ini: Invalid argument
I tried using with and without the quotes but it makes no difference.
Any idea what should I change here?
Thanks!
Try this instead:
FORFILES /M c:\me\test_*\config.ini /C "sed -i ^0x22s/showIntro.*/showIntro\t= false/^0x22 ^0x22#path^0x22"

How to replace text in text file using .SH file script?

So I want to create a script that takes 3 arguments - path to file, exact word to replace and with what to replace it. How to create such thing?
Generally I want6 it to have api like sudo script.sh "C:/myTextDoc.xml" "_WORD_TO_REPLACE_" "WordTo Use"
You don't need a script, a simple sed would do (if you're running under cygwin or a POSIX-compliant OS):
sed -i '' 's/_WORD_TO_REPLACE_/WordTo Use/' "C:/myTextDoc.xml"
Something like this?
#!/bin/bash
sed -e "s/$2/$3/g" <$1 >$1.$$ && cp $1.$$ $1 && rm $1.$$
Alternatively, you can use the single command
sed -i -e "s/$2/$3/g" $1
as Yan suggested. I generally use the first form myself. I have seen systems where -i is not supported (SunOS).
This will replace all instances of the second argument with the third, in the file passed as the first. For example, ./replace file oldword newword
Ruby(1.9+)
$ ruby -i.bak -ne 'print $_.gsub(/WORD_TO_REPLACE/,"New Word")' /path/to/file

How do I use a new-line replacement in a BSD sed?

Greetings, how do I perform the following in BSD sed?
sed 's/ /\n/g'
From the man-page it states that \n will be treated literally within a replacement string, how do I avoid this behavior? Is there an alternate?
I'm using Mac OS Snow Leopard, I may install fink to get GNU sed.
In a shell, you can do:
sed 's/ /\
/g'
hitting the enter key after the backslash to insert a newline.
Another way:
sed -e 's/ /\'$'\n/g'
See here.
For ease of use, i personally often use
cr="\n"
# or (depending version and OS)
cr="
"
sed "s/ /\\${cr}/g"
so it stays on 1 line.
To expand on #sikmir's answer: In Bash, which is the default shell on Mac OS X, all you need to do is place a $ character in front of the quoted string containing the escape sequence that you want to get interpreted. Bash will automatically translate it for you.
For example, I removed all MS-DOS carriage returns from all the source files in lib/ and include/ by writing:
grep -lr $'\r' lib include | xargs sed -i -e $'s/\r//'
find . -name '*-e' -delete
BSD grep would have interpreted '\r' correctly on its own, but using $'\r' doesn't hurt.
BSD sed would have misinterpreted 's/\r//' on its own, but by using $'s/\r//', I avoided that trap.
Notice that we can put $ in front of the entire string, and it will take care of all the escape sequences in the whole string.
$ echo $'hello\b\\world'
hell\world