Multiple expressions in one command using the -e option (sed) - sed

Use the –e option to include 2 replace commands for an example file:
1 to replace all “erors” with “errors” and
1 to replace all last words with “final.”
What command will do this?

This would work:
sed 's/erors/errors/g;s/last/final/g'
As well as:
sed -e 's/erors/errors/g' -e 's/last/final/g'

In awk you can do
cat file
these are all erors that I have
awk '{sub(/erors/,"errors");$NF="final"}1' file
these are all errors that I final

Related

Parse file and insert new line after each occurrence

On a Unix system I am trying to add a new line in a file using sed or perl but it seems I am missing something.
Supposing my file has multiple lines of texts, always ending like this {TNG:}}${1:F01.
I am trying to find a to way to add a new line after the }$, in this way {1 should always start on a new line.
I tried it by escaping $ sign using this:
perl -e '$/ = "\${"; while (<>) { s/\$}\{$/}\n{/; print; }' but it does not work.
Any ideas will be appreciated.
give this a try:
sed 's/{TNG:}}\$/&\n/' file > newfile
The sed will by default use BRE, that is, the {}s are literal characters. But we must escape the $.
kent$ cat f
{TNG:}}${1:F01.
kent$ sed 's/{TNG:}}\$/&\n/' f
{TNG:}}$
{1:F01.
With perl:
$ cat input.txt
line 1 {TNG:}}${1:F01
line 2 {TNG:}}${1:F01
$ perl -pe 's/TNG:\}\}\$\K/\n/' input.txt
line 1 {TNG:}}$
{1:F01
line 2 {TNG:}}$
{1:F01
(Read up on the -p and -n options in perlrun and use them instead of trying to do what they do in a one-liner yourself)

Trying to overwrite a string that has single quotes using Perl or sed in the terminal

I have the following line in a file:
$app-assets:"/assets/";
I am trying to use sed in the terminal to overwrite that line to read as follows:
$app-assets:"http://www.example.com/assets/";
I have tried the following but it does not work:
sed -i \'\' -e \'s/app-assets:"/assets/"/app-assets:"http://www.example.com/assets/"/g\' myfile.txt
I am fine using Perl if easier.
Use the following sed approach:
sed -i 's~\(\$app-assets:"\)\(/assets/\)"~\1http://www.example.com\2"~' myfile.txt
~ here is treated as sed subcommand separator
sed 's/app-assets:\"\/assets\/\";/app-assets:\"http:\/\/www\.example\.com\/assets\/\";/g' filename

Sed Remove 3 last digits from string

27211;18:05:03479;20161025;0;0;0;0;10991;0;10991;000;0;0;000;1000000;0;0;000;0;0;0;82
Second string after ; is time. gg:mm:sssss:. I just want to be gg:mm:ss:
Like so:
27211;18:05:03;20161025;0;0;0;0;10991;0;10991;000;0;0;000;1000000;0;0;000;0;0;0;82
I tried with cut but it deletes everything after n'th occurance of character, and for now I am stuck, please help.
give this one liner a try:
awk -F';' -v OFS=";" 'sub(/...$/,"",$2)+1' file
It removes the last 3 chars from column 2.
update with sed one liner
If you are a fan of sed:
sed -r 's/(;[^;]*)...;/\1;/' file
With sed:
sed -r 's/^([^;]+;[^;]+)...;/\1;/' file
(Or)
sed -r 's/^([^;]+;[0-9]{2}:[0-9]{2}:[0-9]{2})...;/\1;/' file
It also can be something like sed 's/(.*)([0-9]{2}\:){2}([0-9]{3})[0-9]*\;(.*)/\1\2\3\4/g'
It is not very clean, but at least is more clear for me.
Regards
I'd use perl for this:
perl -pe 's/(?<=:\d\d)\d+(?=;)//' file
That removes any digits between "colon-digit-digit" and the semicolon (first match only, not globally in the line).
If you want to edit the file in-place: perl -i -pe ...
With sed:
sed -E 's/(:[0-9]{2})[0-9]{3}/\1/' file
or perl:
perl -pe's/:\d\d\B\K...//' file

Better way to fix mocha lcov output using sed

Due to the know prob of mocha-lcov-mocha breaking file paths, I need to fix the current output paths that looks like this:
SF:Vis/test-Guid.coffee
SF:Vis/Guid.coffee
SF:Vis/test-Vis-Edge.coffee
SF:Vis/Vis-Edge.coffee
into
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
I'm not very good with sed, but I got it to work using:
mocha -R mocha-lcov-reporter _coverage/test --recursive | sed 's,SF:,SF:src/,' | sed s',SF.*test.*,SF:test//&,' | sed s',/SF:,,' | sed s',test/src,test,' | ./node_modules/coveralls/bin/coveralls.js
which is basically doing 4 sed commands in sequence
sed 's,SF:,SF:src/,'
sed s',SF.*test.*,SF:test//&,'
sed s',/SF:,,'
sed s',test/src,test,'
my question is if there is a way to do with this one sed command, or use another osx/linux command line tool
Initially put "src/" after every ":" and then if "test" is found on the line replace "src" with "test":
$ sed 's,:,:src/,;/test/s,src,test,' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
You could put all the sed commands in a file, one line per command, and just use "sed -e script". But if you just want it on a single command-line, separate with semicolons. This works for me:
sed 's,SF:,SF:src/,;s,SF.*test.*,SF:test//&,;s,SF:,,;s,test/src/,test,'
sed command
sed '\#test#!{s#SF:Vis/#SF:src/Vis/#g};\#SF:Vis/test#{s#SF:Vis/test#SF:test/Vis/test#g};' my_file
Here is an awk version:
awk -F: '/SF/ {$0=$1FS (/test/?"test/":"src/")$2}1' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
How it works:
awk -F: ' # Set field separator to ":"
/SF/{ # Does line start with "SF"?
$0=$1FS (/test/?"test/":"src/")$2 # Recreat String by adding "test" if line contains "test", else "src"
}
1 # Print all lines
' file # read the file

Sed: can't define the pattern correctly, can you please assist?

I'm trying to add "ARG1$" to the end of this line:
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $
I've tried:
sed -e 's/^command\[check_net_speed\]$/$ARG1$/g' /etc/nagios/nrpe.cfg
sed -e 's/.*speed.*/$ARG1$/g' /etc/nagios/nrpe.cfg
But none did the trick... what's the right way to catch the pattern of the "check_net_speed" command and add "ARG1$" at the end of the line, so the line will look like this:
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $ARG1$
Something like
sed -e 's/^command\[check_net_speed\].*/&ARG1$/g' input
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $ARG1$
Change your sed command like below,
sed -e '/^command\[check_net_speed\]/s~$~ARG1$~' file
/^command\[check_net_speed\]/ matches the lines which starts with command[check_net_speed] and it do the replacement on those matched lines.
$ in the regex part means end of the line. So the above command replaces the end of the line anchor with ARG1$
Example:
$ echo 'command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $' | sed -e '/^command\[check_net_speed\]/s~$~ARG1$~'
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $ARG1$
$ has a special meaning: end of line. To treat it as a literal, you have to escape it:
sed '/^command\[check_net_speed\].*\$/s/$/ARG1$/' file
This will replace the end of line (indicated by $ alone) with the string ARG1$. So at the end, ARG1$ will be appended to the line.
The /command/ part is used to perform this replacement only in the lines containing the string command.
Test
$ cat a
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $
ddd
$ sed '/^command\[check_net_speed\].*\$/s/$/ARG1$/' a
command[check_net_speed]=/usr/lib64/nagios/plugins/check_net_speed.sh $ARG1$
ddd
As a supplement to nu11p01n73R's answer. Use
sed -e 's/^command\[check_net_speed\].*\$$/&ARG1$/g;q' /etc/nagios/nrpe.cfg
;q after substitution command means stop processing the rest of this file after first match.