OSX Terminal: how to add same item to each line of a csv file? - linux

I have got a csv file like this:
120,256,300
36,255,12
etc...
I want to add a fixed string like 'USA' to all lines in order to obtain:
120,256,300,USA
36,255,12,USA
etc...
How can I do that?
Thanks

From a text processing point of view that CSV file is plain text in this context, you just want to attach , USA to each line.
The easiest (and operationally least expensive) way to do so is probably:
sed -i '' 's/$/, USA/' file
What this does is to instruct sed to look for the end of line $ and "replace" it with , USA. As sed is line-based this obviously doesn't actually trim out the new line of the file.
-i '' instructs sed to make the changes in-line without creating a backup file.
If you wanted a backup you can put the desired extension instead of '', e.g. -i .bak.

You can just use sed: cat <input-file> | sed 's/\(.*\)/\1, USA/'.
Here s is the substitute command, which uses the following character as a separator between a regular expression and a substitution. For the regular expression, the escaped parenthesis are used to create a capture group, the regex .* captures the entire line. For the substitution, the \1 inserts the first capture group, and then the , USA text is appended.
You can perform the replacement in place using: sed -i .bak 's/\(.*\)/\1, USA/' <input-file>

Related

How to edit string at a line in file in linux

I have file which contains text at line 30 which is:
Icon="\<some path which we do not know\icon.png"
I want to replace above with:
Icon="\home\user\Img\Icons\icon.png"
What is the best way to do it.?
Thanks.
Best way:
perl -pi -e 's/\\<some path which we do not know/\\home\\user\\Img\\Icons/' text.txt
Perl approach is more preferred than sed, because of Unix compatibility.
You can either use an editor to do this manually or if you prefer to do it non interactively, you can use a small shell pipeline and sed.
sed `3 s/big path/custom path/` input_file.txt
where 3 is the line number, big path is what you want to replace and custom path is what you to want to replace it with. input_file.txt is your input file. This will print the replaced file onto the screen which you can redirect into another file using the > operator.
As a concrete example, suppose I have this file (input_file.txt)
Header
Random test
/bad/path/to/some/directory/icon.png
/bad/path/to/some/directory/icon.png
Footer
Now I'm going to run my command like so.
cat input_file.txt | sed '4 s/\/bad\/path\/to\/some\/directory\//\/home\/noufal\//'
and I get
Header
Random test
/bad/path/to/some/directory/icon.png
/home/noufal/icon.png
Footer
Notice that it has changed only the 4th line. The extra \ characters in the command are to escape the / character which has special meaning for sed.
you can use vim to find and replace your strings http://vim.wikia.com/wiki/Search_and_replace or use 'sed' command

Sed command with exact variable change

I want to replace exact word by sed command with variable. My file looks like this:
//module xyz
module xyz
Suppose I have the following shell variables defined:
var1='module xyz'
var2='module abc'
I want to change xyz to abc in uncommented line only(module xyz)
So after executing command output should be
//module xyz
module abc
I do not want to change commented line (//module xyz)
currently I am using sed command as,
sed -i "s|$var1|$var2|g" file_name
But this command doesn't work. It also replace commented line. How can I only replace the line that isn't commented?
Assuming that you know the pattern is at the start of the line, you can use this:
sed "s|^$var1|$var2|" file_name
That is, add an anchor ^, so that the match has to be at the start of the line.
I removed the -i switch so you can test it and also the g modifier, which isn't necessary as you only want to do one substitution per line.
It's worth mentioning that using shell variables in sed is actually quite tricky to do in a reliable way, so you should take this into account.
Your shell variable assignment should be quoted if there is space. Like:
var1="foo bar blah"
You can add pattern, "the lines don't start with // " to your sed command, so that do your substitution only for those lines
This line should work for your example:
sed -i "\#^//#\!s/$var1/$var2/g" file
the ! needs to be escaped, because we used double quote
since your pattern (comment) has slash (/), I used other char as regex separator
This command will only do substitution on lines not starting with //. If there are leading spaces, you may want to adjust the pattern ^//
You need to identify a pattern so that lines containing that pattern should not be processed.
Assuming that // will exist only in commented lines you can use
sed -i '/\/\// !s/$var1/$var2/g' file_name
/\/\// will enable sed to identify lines which contain the pattern //, and !s will enable you to skip those lines.

Filter out only matched values from a text file in each line

I have a file "test.txt" with the lines below and also lot bunch of extra stuff after the "version"
soainfra_metrics{metric_group="sca_composite",partition="test",is_active="true",state="on",is_default="true",composite="test123"} map:stats version:1.0
soainfra_metrics{metric_group="sca_composite",partition="gello",is_active="true",state="on",is_default="true",composite="test234"} map:stats version:1.8
soainfra_metrics{metric_group="sca_composite",partition="bolo",is_active="true",state="on",is_default="true",composite="3415"} map:stats version:3.1
soainfra_metrics{metric_group="sca_composite",partition="solo",is_active="true",state="on",is_default="true",composite="hji"} map:stats version:1.1
I tried:
egrep -r 'partition|is_active|state|is_default|composite' test.txt
It's displaying every line, but I need only specific mentioned fields like this below,ignoring rest of the data/stuff or lines
in a nut shell, i want to display only these fields from a line not the rest
partition="test",is_active="true",state="on",is_default="true",composite="test123"
partition="gello",is_active="true",state="on",is_default="true",composite="test234"
partition="bolo",is_active="true",state="on",is_default="true",composite="3415"
partition="solo",is_active="true",state="on",is_default="true",composite="hji"
If your version of grep supports Perl-style regular expressions, then I'd use this:
grep -oP '.*?,\K[^}]+' file
It removes everything up to the first comma (\K kills any previous output) and prints everything up to the }.
Alternatively, using awk:
awk -F'}' '{ sub(/[^,]+,/, ""); print $1 }' file
This sets the field separator to } so the part you're interested in is the first field. It then uses sub to remove the part up to the first comma.
For completeness, you could also use sed:
sed 's/[^,]*,\([^}]*\).*/\1/' file
This captures the part after the first , up to the } and replaces the content of the line with it.
After the grep to pick out the lines you want, use sed to edit the lines:
sed 's/.*\(partition[^}]*\)} map.*/\1/'
This means: "whenever you see anything .*, followed by partition and
any number of non-}, then } map and anything else, grab the part
from partition up to but not including the brace \(...\) as group 1.
The replacement text is just group 1 \1.
Use a pipe | to connect the output of egrep to the input of sed:
egrep ... | sed ...
As far as i understood your file might have more lines you don't want to see, so i would use:
sed -n 's/.*\(partition.*\)}.*/\1/p' file
we use -n p to show only lines where we made substitution. The substitution part just gets the part of the line you need substituting the whole line with the pattern.
This might work for you (GNU sed):
sed -r 's/(partition|is_active|state|is_default|composite)="[^"]*"/\n&\n/g;s/[^\n]*\n([^\n]*)\n[^\n]*/\1,/g;s/,$//' file
Treat the problem as if it were a "decomposed club sandwich". Identify the fillings, remove the bread and tidy up.

Linux/Unix Replacing a pattern in a string and saving to a new file with sed

I have a task, to replace specific pattern in a string.
So far I tried commands like sed -e 's/text_to_find/text_to_replace/g' file
but I don't why it changed all string, not just a part which I wanted to change.
what I want to do is in every string that contains word china to add this Tomas_proxy.lt
To make it very clear, what I am looking for, there is file I am using:
987173,businesswirechina.com
988254,chinacfa.com
988808,1012china.com
989146,chinawise.ru
989561,chinaretailnews.com
989817,mobileinchina.cn
990894,cmt-china.com.cn
990965,chinajoy.net
992753,octaviachina.com
993238,chinadftzalex.com
993447,china-kena.com
And this is I would like to see in a new file
987173,Tomas_proxy.lt/businesswirechina.com
988254,Tomas_proxy.lt/chinacfa.com
988808,Tomas_proxy.lt/1012china.com
989146,Tomas_proxy.lt/chinawise.ru
989561,Tomas_proxy.lt/chinaretailnews.com
989817,Tomas_proxy.lt/mobileinchina.cn
990894,Tomas_proxy.lt/cmt-china.com.cn
990965,Tomas_proxy.lt/chinajoy.net
992753,Tomas_proxy.lt/octaviachina.com
993238,Tomas_proxy.lt/chinadftzalex.com
993447,Tomas_proxy.lt/china-kena.com
P.s. This is just example file, In real file I am using, not every line has word china ,there is 100000 strings and lets say about 500 has china
You can try this sed command
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
or
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName > NewFile
or
sed -i.bak 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
sed '/[Cc]hina/s/,/,Tomas_proxy.lt\//' File > New_File
In all the lines matching china / China (change if you don't want case check), replace the first , with ,Tomas_proxy.lt/. Output redirected to New_File.
If you want the changes to be in the same file, use -i (inplace option):
sed -i '/[Cc]hina/s/,/,Tomas_proxy.lt\//' File
Her is an awk version:
awk '/china/ {sub(/,/,"&Tomas_proxy.lt/")} 1' file
987173,Tomas_proxy.lt/businesswirechina.com
988254,Tomas_proxy.lt/chinacfa.com
988808,Tomas_proxy.lt/1012china.com
989146,Tomas_proxy.lt/chinawise.ru
989561,Tomas_proxy.lt/chinaretailnews.com
989817,Tomas_proxy.lt/mobileinchina.cn
990894,Tomas_proxy.lt/cmt-china.com.cn
990965,Tomas_proxy.lt/chinajoy.net
992753,Tomas_proxy.lt/octaviachina.com
993238,Tomas_proxy.lt/chinadftzalex.com
993447,Tomas_proxy.lt/china-kena.com
Search for china, if found, replace , with ,Tomas_proxy.lt/, then print all lines.
sed '/china/ s#,#,Tomas_proxy.lt/#' YourFile
based on your sample and assuming first , is the place to insert your text in the line

Replace version number in file with sed in Bash script

In my project.pro file I have:
DEFINES += VERSION=\\\"1.13.1\\\"
I'd like to replace whatever the current version number is, with a new one in a Bash script:
VERSION_MAJOR=1
VERSION_MINOR=14
VERSION_PATCH=1
sed -i "s/\([0-9]+.[0-9]+.[0-9]+\)/\1${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}/" project.pro
Why is that not working?
So far I have managed to get either no matches at all or then some weird replace-only-the-last-number substitutions.
You may use this sed:
sed -i.bak -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/" project.pro
Few problems in your attempt:
Without extended regex mode (-E), + cannot be used unescaped.
dot needs to be escaped in a regex
No need to use a capture group and back-reference \1.
PS: .bak is extension of backup file so that you can get original file, in case of a wrong substitution.

Resources