Replacing text with shell script ending with an extension - bash

I need some inputs on how to achieve this:
I need to replace a text in a file, using shell script, the text which i need to replace ends with .ear, for example below:
/home/export/files/list/aa_bb_cc.ear
The shell script should replace the aa_bb_cc.ear with say, replaced.ear.
That is the line after substitution should be:
/home/export/files/list/replaced.ear
I did read online about this, and came to know about sed command. The problem which i have, is that i don't know before hand what the text to be replace would be, that is, i know the text to be replace would be something *.ear (in an attempt to match aa_bb_cc.ear)
Now, how can I do this? I tried to use "*" in sed however it didn't work

With GNU sed:
sed 's|[^/]*\.ear|replaced.ear|' file
or
sed 's|[^/]*\(\.ear\)|replaced\1|' file
If you want to edit your file "in place" use sed's option -i.
See: The Stack Overflow Regular Expressions FAQ

$ echo /home/export/files/list/aa_bb_cc.ear | sed 's/[^/]*\.ear/xxx.ear/'
/home/export/files/list/xxx.ear
since regex match is greedy, you need to specify to match non-slash char. Dot matches any char, so to specify literal dot you have to escape with back-slash.

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

Sed substitution places characters after back reference at beginning of line

I have a text file that I am trying to convert to a Latex file for printing. One of the first steps is to go through and change lines that look like:
Book 01 Introduction
To look like:
\chapter{Introduction}
To this end, I have devised a very simple sed script:
sed -n -e 's/Book [[:digit:]]\{2\}\s*(.*)/\\chapter{\1}/p'
This does the job, except, the closing curly bracket is placed where the initial backslash should be in the substituted output. Like so:
}chapter{Introduction
Any ideas as to why this is the case?
Your call to sed is fine; the problem is that your file uses DOS line endings (CRLF), but sed does not recognize the CR as part of the line ending, but as just another character on the line. The string Introduction\r is captured, and the result \chapter{Introduction\r} is printed by printing everything up to the carriage return (the ^ represents the cursor position)
\chapter{Introduction
^
then moving the cursor to the beginning of the line
\chapter{Introduction
^
then printing the rest of the result (}) over what has already been printed
}chapter{Introduction
^
The solution is to either fix the file to use standard POSIX line endings (linefeed only), or to modify your regular expression to not capture the carriage return at the end of the line.
sed -n -e 's/Book [[:digit:]]\{2\}\s*(.*)\r?$/\\chapter{\1}/p'
As an alternative to sed, awk using gsub might work well in this situation:
awk '{gsub(/Book [0-9]+/,"\\chapter"); print $1"{"$2"}"}'
Result:
\chapter{Introduction}
A solution is to modify the capture group. In this case, since all book chapter names consist only of alphabetic characters I was able to use [[:alpha:]]*. This gave a revised sed script of:
sed -n -e 's/Book [[:digit:]]\{2\}\s*\([[:alpha:]]*\)/\\chapter{\1}/p'.

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

Removing chars until a numeric is found from array item Bash

I have the line of text within a text file. The line looks something like this:
xxxx,xxxxx,xxxxxx,xxxxx,xxxx,NL-1111 xx,xxxx,xxx
The NL- is an identifier for the country so this could be anything. I would like to remove the NL- part from the line so it looks like this:
xxxx,xxxxx,xxxxxx,xxxxx,xxxx,1111 xx,xxxx,xxx
And write the file afterwards.
Thanks in advance.
Another solution close to sed's ones, but with perl:
perl -i -pe "s/(?<=,)[a-zA-Z]{2}-//g" file.txt
It uses look behind expression, so that you don't need to repeat the comma in the replacement part.
something like this using sed
sed -i 's/,[A-Z][A-Z]-\([0-9]\+,\)/,\1/i' file.txt
,[A-Z][A-Z]-\([0-9]\+,\)search for comma letter, letter, -, digit(s), comma
,\1keep only the commas and the digits.
iignore case on the letters
thankyou to #chris for proof-reading.
I think the simplest solution here is reading it from the file into a shell variable, then writing it back immediately and using the pattern substitution variation of parameter expansion:
line="$(<file)"; echo "${line/[a-zA-Z][a-zA-Z]-}" >|file;
I would warn you against solutions that use sed-in-place functionality. I've found that sed behavior differs on different platforms with respect to the -i option. On Mac you have to give an empty argument ('') to the -i option, while on Cygwin you must not have an empty argument following the -i. To get platform compatibility you'd have to test what platform you're on.
sed might do the trick: remove the string ",NL-", "BE-" etc from anywhere in the file:
sed -i 's/,[A-Z][A-Z]-/,/' file.txt

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