BASH: insert text in a specific position - bash

I would like to find a solution to add some characters in a string
Example
folder/dir/directory/file.txt
shares/page.html
etc/downloads/torrent.torrent
Should become
.folder.old/dir/directory/file.txt
.shares.old/page.html
.etc.old/downloads/torrent.torrent
How can i do that? 'grep' would be a correct choose?
Thank you

Use sed instead of grep:
sed -i.bak 's#^\([^/]*\)#.\1.old#'
Note that -i will save the result in the original file itself. -i.bak will save your original file with .bak extension in case something goes wrong.

grep only searches, it doesn't do replacement. You want sed:
sed -i.bak 's#^\([^/]*\)#.\1.old#'
^ means beginning of the line
\(...\) is capturing parentheses, the pattern it matches becomes \1 in the replacement.
[^/] matches anything but /
* is zero or more of the preceding

Related

Remove prefix of each line in a file and output to another file using sed

I have a source code file in which comments are prefixed with // (ie. double slashes and an empty space), I want to convert the source code into a document so I tried to cat file.c and pipe it to sed, the thinking is to replace "double slash and a space" if a line starts with it, with empty string, but it looks like the slash has some special meaning in sed, so what's the best way of constructing the sed arguments?
Thanks!
If you want to remove the special meaning of / from sed then following may help you in same.
sed 's/^\/\/ //g' Input_file
So I am escaping / here by using \ before it, so it will be taken as a literal character rather than it's special meaning in code. Also if you are happy with above command's result then use -i to save the changes in Input_file itself. Hope this helps.
The slash only has meaning if you allow it.
sed 's#^// +##' < file.c

Using sed to check make sure each line only has numbers and a comma?

I have a text file that looks like this:
0,16777215
16807368,16807368
621357328,621357328
621357403,621357403
1380962773,1380962773
1768589474,1768589474
Is there a way to use sed to make sure that each line ONLY has numbers and one comma? If a line is missing the comma, contains letters, is blank, has spaces, etc. - then I want to delete it.
With sed:
sed -nr '/^[0-9]+,[0-9]+$/p' File
To edit the file in-place:
sed -nri '/^[0-9]+,[0-9]+$/p' File
A portable solution:
sed -nE '/^[0-9]+,[0-9]+$/p' File
sed -e '/^[0-9]\+,[0-9]\+$/ !d' file
The address is a regular expression. If the line does not match the regular expression, the d (delete) command is applied. (The exclamation mark (!) inverts the condition.)

Replace content in a file or line matching a regular expression using SED

How to replace a line / part of a line in a file using SED command?
search_text_1_server=value.env_1.path_to_file
search_text_2_server=value.env_1.path_to_file
search_text_3_server=value.env_1.path_to_file
some_other_key=value.env_1.another_path
Now I want a sed command to find the lines which match the regular expression search_text_{any}_server and then replace env_1 with env_2
Found the regular expression to find the required lines.
^search_text_[a-z_]\*_server.*$
Now how to add the SED syntax to replace
PS : I am not an expert in shell
Your regex is close. You can use:
sed -E 's/^(search_text_[a-z_]*_server=.*)env_1\./\1env_2\./' file
search_text_1_server=value.env_2.path_to_file
search_text_2_server=value.env_2.path_to_file
search_text_3_server=value.env_2.path_to_file
some_other_key=value.env_1.another_path
Assuming country code to be two alphabets, you could do
sed -Ei 's/(search_text_[a-z]{2}_server=value\.)env_1/\1env_2/' file
should do it.
What's happening here
[a-z]{2} checks for two alphabets which make a country code
sed s command is for substitution -> s/pattern/replacement
() selects the matched regex pattern for reuse, Note \1 for reuse
-i is the inplace edit option of sed which makes changes permanent in the file

How to remove line matching specific pattern from a file

I know sed could be used to delete specific line from file:
sed -i "/pattern/d" file
While the pattern of my case includes slash, like /var/log,
So I know I need escape: sed -i "/\/tmp\/dir/d" file
However, for my case, the pattern is dynamic, should be a variable
in a shell file, so I have to convert the variable value to replace
"/" with "\\/", then got this:
sed -i "/^${pattern_variable//\\//\\\\\\/}$/d" file
My question is, is there any better implementation which is more readable or simpler? Not only sed, other utility is also acceptable. Is it possible to handle not only slash but also other various symbols, like backslash or # ()?
you can use char other than /:
sed "\#$varHasSlash#d"
example:
kent$ foo="b/c"
kent$ echo "a
ab/cd
e"|sed "\#$foo#d"
a
e

remove absolute path using sed command

I have file which contain following context like
abc...
include /home/user/file.txt'
some text
I need to remove include and also complete path after include.
I have used following command which remove include but did not remove path.
sed -i -r 's#include##g' 'filename'
I am also trying to understand above command but did not understand following thing ( copy paste from somewhere)
i - modify file change
r - read file
s- Need input
g - Need input
Try this,
$ sed '/^include /s/.*//g' file.txt
abc...
some text
It remove all the texts in a line which starts with include. s means substitute. so s/.*//g means replace all the texts with null.g means global. The substitution will be applied globally.
OR
$ sed '/^include /d' file.txt
abc...
some text
d means delete.
It deletes the line which starts with include. To save the changes made(inline edit), your commands should be
sed -i '/^include /s/.*//g' file.txt
sed -i '/^include /d' file.txt
I your case if you just want to delete the second line, you can use:
sed -i '2d' file
If you want to explore something about linux commands then man pages are there for you.
Just go to terminal and type:
man sed
as per your question, The above command without -i will show the file content on terminal by deleting the second line from the input file. However, the input file remains unchanged. To update the original file or to make the changes permanently in the source file, use the -i option.
-i[SUFFIX], --in-place[=SUFFIX] :
edit files in place (makes backup if extension supplied)
-r or --regexp-extended :
option is to use extended regular expressions in the script.
s/regexp/replacement/ :
Attempt to match regexp against the pattern space. If success‐
ful, replace that portion matched with replacement. The
replacement may contain the special character & to refer to that
portion of the pattern space which matched, and the special
escapes \1 through \9 to refer to the corresponding matching
sub-expressions in the regexp.
g G : Copy/append hold space to pattern space.
grep -v
This is not about learning sed, but as an alternative (and short) solution, there is:
grep -v '^include' filename_in
Or with output redirection:
grep -v '^include' filename_in > filename_out
-v option for grep inverts matching (hence printing non-matching lines).
For simple deletion that's what I'd use; if you have to modify your path after the include, stick with sed instead.
You can use awk to just delete the line:
awk '/^include/ {next}1' file
sed -i -r 's#include##g' 'filename'
-i: you directly modify the treated file, by default, sed read a file, modify the content via stdout (the original file stay the same).
-r: use of extended regular expression (and not reduce to POSIX limited one).This is not necessary in this case due to simple POSIX compliant action in action list (the s### string).
s#pattern#NewValue#: substitute in current line the pattern (Regular Expression) with "Newvalue" (that also use internal buffer or specific value). The traditionnal form is s/// but in this case, using / in path (pattern or new value) an alternate form is used to avoid to escape all / in pattern or new value
g: is an option of s### that specify change EVERY occurence and not the first (by default)
so here it replace ANY occurence of include by nothing (remove) directly into your file
As per the Avinash Raj solution you got what you want but you want some explaination about some parameter used in sed command
First one is
command: s for substitution
With the sed command the substitute command s changes all occurrences of the regular expression into a new value. A simple example is changing "my" in the "file1" to "yours" in the "file2" file:
sed s/my/yours/ file1 >file2
The character after the s is the delimiter. It is conventionally a slash, because this is what ed, more, and vi use. It can be anything you want, however. If you want to change a pathname that contains a slash - say /usr/local/bin to /common/bin - you could use the backslash to quote the slash:
sed 's/\/usr\/local\/bin/\/common\/bin/' <old >new
/g - Global replacement
Replace all matches, not just the first match.
If you tell it to change a word, it will only change the first occurrence of the word on a line. You may want to make the change on every word on the line instead of the first then add a g after the last delimiter and use the work-around:
Delete with d
Delete the pattern space; immediately start next cycle.
You can delete line by specifying the line number. like
sed '$d' filename.txt
It will remove last line of file
sed '2 d' file.txt
It will delete second line of file.
-i option
This option specifies that files are to be edited in-place. GNU sed does this by creating a temporary file and sending output to this file rather than to the standard output.
To modify file actully you can use -i option without it sed command repressent changes on stdout not actual file. You can take backup of original file before modification by using -i.bak option.
-r option
--regexp-extended
Use extended regular expressions rather than basic regular expressions. Extended regexps are those that egrep accepts; they can be clearer because they usually have less backslashes, but are a GNU extension and hence scripts that use them are not portable.

Resources