using SED to replace 'price' with 'g:price' - sed

this is returning the error indicating that ':' is a bad character, i used this:
sed "s/price/ /g:price//g" file.txt > outputfile.txt
?

Try escaping it:
sed "s/price/g\:price/g" file.txt > outputfile.txt

If you want to change "price" to "g:price" , there is really no need to escape the ":". Also , use single quotes (unless you want to interpolate variables)
$ echo "price" | sed 's/price/g:price/'
g:price

Your problem has not to do with the : character - your command that is wrong for other reasons:
s/price/ /g:price//g
What this command is doing is to replace all prince instances by a whitespace:
s/price/ /g
since the rest of the command makes no sense, sed cannot execute it. What you should do is to remove the / just after price and to remove one of the / at the end of the command. The result will be the one presented by #kurumi answer:
s/price/g:price/
HTH

Related

Substring file name in Unix using sed command

I want to substring the File name in unix using sed command.
File name : Test_Test1_Test2_10082019_030013.csv.20191008-075740
I want the characters after the 3rd underscore or (all the characters after Test2 ) i need to be printed .
Can this be done using sed command?
I have tried this command
sed 's/^.*_\([^_]*\)$/\1/' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
but this is giving result as 030013.csv.20191008-075740
I need it from 10082019_030013.csv.20191008-075740
Thanks
Neha
To remove from the beginning up to including the 3rd underscore you can use
sed 's/^\([^_]*_\)\{3\}//' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
This removes the initial part that consists of 3 groups of (any number of non-underscore characters followed by an underscore). The result is
10082019_030013.csv.20191008-075740
If you use GNU sed you can switch it to extended regular expressions and omit the backslashes.
sed -r 's/^([^_]*_){3}//' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
Could you please try following.
sed 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\(.*\)/\4/' Input_file
Or as per Bodo's nice suggestion:
sed 's/[^_]*_[^_]*_[^_]_\(.*\)/\1/' Input_file
This might work for you (GNU sed):
sed 's/_/\n/3;s/.*\n//;t;s/Test2/\n/;s/.*\n//;t;d' file
Replace the third _ by a newline and then remove everything upto and including the first newline. If this succeeds, bail out and print the result. Otherwise, try the same method with Test2 and if this fails delete the entire line.

remove last delimiter in sed/awk/perl

An input file is given, each line of which contains delimited data with extra delimiter at the end in data/header with or without enclosures.
Extra delimiter at the end it can contain with/without spaces.
Scenario 1 : Header & Data contain extra delimiter at the end
eno|ename|address|
A|B|C|
D|E|F|
Scenario 2 : Header doesn't contain extra delimiter at the end
eno|ename|address
A|B|C|
D|E|F|
Scenario 3 : With enclosures
eno|ename|address|
1|2|"A"|
Final output has to be like
Scenario 1 :
eno|ename|address
A|B|C
D|E|F
Scenario 2 :
eno|ename|address
A|B|C
D|E|F
Scenario 3 :
eno|ename|address
1|2|"A"
Solution which i have tried so far. But below solution won't work for all three scenarios is there anyway which i can make single command to support all the three scenarios in Sed/Awk/Perl
perl -pne 's/(.*)\|/$1/' filename
Could you please try following.
awk '{gsub(/\|$|\| +$/,"")} 1' Input_file
Explanation:
gsub is awk function which Globally substitute matched pattern with mentioned value.
Explanation of regex:
/\|$|\| +$/: Here there are 2 parts of regex. First is /\|$ and second is +$ which is segrigated with | where 1st regex is for removing | from last of the line and second regex removes | with space at last. So it basically takes care of both conditions successfully.
perl -lpe 's/\|\s*$//' file
will do it. That only removes pipes followed by optional whitespace at the end of each line. Note the $ line anchor.
I added the -l since each line's newline will get removes by the s/// command, and -l will put it back.
All you need is this:
sed 's/|$//'
A bit more generic. Let's assume you have the same problem, but with different field separators in different files. Some of these field separators are regular expressions (e.g. a sequence of blanks), others are just a single character c. With a tiny little awk program you can get far:
# remove_last_empty_field.awk
# 1. Get the correct `fs`
BEGIN { fs=FS; if(length(FS)==1) fs=(FS==" ") ? "[[:blank:]]+" : "["FS"]" }
# remove the empty field
{ sub(fs"$","") }
# Print the current record
1
Now you can run this on your various files as:
$ awk -f remove_last_empty_field.awk f1.txt
$ awk -f remove_last_empty_field.awk FS="|" f2.txt
$ awk -f remove_last_empty_field.awk FS="[|.*]" f3.txt
perl -pi -e 's/\|$//' Your_FIle

sed replacing special string quota

sed is still giving me headaches, so a little help is extremely appreciated.
In a file I have a string like:
SOME_TEXT="variables"
What I want to accomplish is to add a piece of text (variable) to either the end or the begging of the string for that text.
I tried to use variations of:
sed -i '/^SOME_TEXT="/ s/$/ SOME_TEXT="new text'/' filename
but that is failing, so clearly the quota for the string I want to add to is messing up the syntax.
LE:
A variation further is that I have a variable that I want to use as the replace in that syntax, so I have this:
sed -i "s/^SOME_TEXT="/SOME_TEXT=" $variable/" file
This actually produces this output, as it picks up incorrectly the opening/closing quotas:
SOME_TEXT = text_variable" initial text continuation
So how can I properly close the trailing quota so that I can use the variable after it?
I used
sed 's/^SOME_TEXT="/SOME_TEXT="new text/' filename
and it showed:
SOME_TEXT="new textvariables"
Is that what you want?
Escape the '"' characters with a '\' so that they don't terminate your regex string.
sed -i "s/^TEXT=\"/TEXT=\" $variable/"

Escaping characters in sed

I am trying to replace the value of a couple of php database array variables with sed, but it is not working as expected
Here is an example:
echo \$DB['TYPE']='MYSQL' | sed "s|^$DB['TYPE']=.*$|$DB['TYPE']='POSTGRESQL'|g"
Im trying to replace $DB['TYPE']='MYSQL' with $DB['TYPE']='POSTGRESQL'
I escaped it this way but does not work, I keep getting $DB[TYPE]=MYSQL
echo \$DB['TYPE']='MYSQL' | sed "s|^\$DB[\'TYPE\']=.*$|\$DB[\'TYPE\']=\'POSTGRESQL\'|g"
Thanks in advance
I'm trying to replace $DB['TYPE']='MYSQL' with $DB['TYPE']='POSTGRESQL'
You can use:
sed "s|\(\$DB\['TYPE'\]=\)'MYSQL'|\1'POSTGRESQL'|g" file
Reduce duplication as much as possible:
$ echo "\$DB['TYPE']='MYSQL'" |
sed "s|^\(\$DB\['TYPE'\]='\)[^']*|\1POSTGRES|"
$DB['TYPE']='POSTGRES'
You use line anchors so the g modifier is useless -- the pattern can match at most once per line.
You need double quotes on the echo line. Without them, you get the shell seeing the single quotes as quote characters, not literal characters:
$ echo \$DB['TYPE']='MYSQL'
$DB[TYPE]=MYSQL
In you example sed doen"t find the exact phrase. Why don't you just exchange the word you want to exchange like
echo \$DB['TYPE']='MYSQL' | sed "s|MYSQL|POSTGRESQL|g"
?
I ended up going with this
echo "\$DB['TYPE']='MYSQL'" | sed "s|^\$DB\['TYPE'\]=.*$|\$DB\['TYPE'\]='POSTGRESQL'|"
It works as expected. Thanks guys.

How to conditionally remove first line only with sed when it matches?

Can I use sed to check the first line of some command's output (to stdout) and delete this very first line if it matches a certain pattern?
Say, the command's output is something like this:
"AB"
"CD"
"E"
"F"
I want it to become:
"CD"
"E"
"F"
But when the first line is "GH", I don't want to delete the line.
I tried this, but it doesn't work:
<some_command> |sed '1/<pattern>/d'
The shell told me:
sed: 0602-403 1/<pattern>/d is not a recognized function.
I only want to use sed to process the first line, leaving the other lines untouched.
What is the correct syntax here?
This might work for you:
sed -e '1!b' -e '/GH/!d' file
You want to reference the 1st line, then say delete:
$ sed '1 d' file
No need for any pattern if you know which line you want to delete.
With a pattern, use this syntax:
$ sed '0,/pattern/ d' file
This is what you want:
$ sed '1{/"GH"/!d}' file
sed '1{/<pattern>/{/GH/!d}}' input
The error in your expression can be fixed like this:
sed '1{/<pattern>/d}' input