How to delete 1 or more matching line(s) while reading a file in bash script [duplicate] - linux

This question already has answers here:
How to pass a variable containing slashes to sed
(7 answers)
Combining two sed commands
(2 answers)
Linux, find replace on a folder of files using a list of items for replacement?
(1 answer)
Closed 4 years ago.
I want to read file using a bash script and delete line(s) which are matching with my specific scenario (line(s) starting with 'z').
my code works fine if the 'inputFile' contains only alphabetic characters.
but, if a line with 'specific characters of sed' (line eg : z-2.10.3.2 x/y/z F (&)[]+* ) then i got an error,(error : sed: -e expression #1, char 29: unterminated `y' command).
#!/bin/bash
inputFile="test.txt"
while IFS= read -r line
do
echo "$line"
if [[ $line == z* ]];
then
sed -i "/$line/d" $inputFile
fi
done < "$inputFile"
i want to delete 'z-2.10.3.2 x/y/z F (&)[]+*' kind of lines, how can i do this...?

As you mentioned you don't need line which has z*
Simply use grep -v
grep -vE "^[[:blank:]]*z" file
I have created one scenario where I have a file which contains
root#ubuntu:~/T/e/s/t# cat file
hello world
sample line 1
sample line 2 world
sample line 3
sample line 4
In my case, I want to remove the line contains "world"
root#ubuntu:~/T/e/s/t# grep -v "world" file
sample line 1
sample line 3
sample line 4
If you want you can redirect your output in another file.

Related

inserting contents of one text file into another in bash [duplicate]

This question already has answers here:
Insert newline (\n) using sed
(4 answers)
Insert contents of a file after specific pattern match
(1 answer)
Closed 1 year ago.
I would like to insert the contents of one text file (with newlines) into another at a predetermined location (after some string):
I tried the following:
the base file:
cat base
ONE
TWO
THREE
the extension:
cat ext
100
200
300
400
500
600
700
800
900
A00
B00
C00
D00
and the script I tried:
#!/bin/bash
ext=$(<ext)
sed -i "s/TWO/TWO\n$ext/" base
which gives me sed: -e expression #1, char 14: unterminated `s' command
If you want to edit a file directly, I always suggest ed instead of the non-standard sed -i (Where different implementions of sed that do support it act differently, a common source of questions here):
printf "%s\n" "/TWO/r ext" w | ed -s base
will insert the contents of file ext after the first line containing TWO in base, and then write the new version of base back to disk.
If you must use sed, the proper invocation will look very similar (No surprise since they're sibling commands):
sed -i '/TWO/r ext' base
(This will insert the ext file after every TWO in base, though, not just the first.)
The key in both is the r command, which reads the contents of the given file and inserts it after a line with the matching address. Works a lot better than trying to read the file contents into a variable and including the text directly in the ed/sed commands.
If you want to insert the contents of a variable after the line, you can use
printf "%s\n" "/TWO/a" "$ext" . w | ed -s base
(As long as the variable doesn't have a line with just a period)
or with GNU sed
sed -i "/TWO/a ${ext//$'\n'/\\\n}" base
to append text after the addressed line.
While the answer given by Shawn shows a possible solution, it does not explain why your attempt did not work.
Note that your variable ext contains line feed characters. Hence, sed sees here a physical line feed. You would get the same error message when typing on the command line (in two lines):
sed -i "s/TWO/TWO\nfoo
/" base
This might work for you (GNU sed):
sed -e '0,/TWO/{/TWO/r extFile' -e '}' baseFile
This will place the file extFile after the first occurrence of the string TWO. The -i option may be used to amend the file in place.
An alternative solution:
sed -e '/TWO/!b;r extFile' -e ':a;n;ba' baseFile
N.B. The use of the -e option to split the commands after the r filename command. The r must be followed by a newline and the -e simulates this on a single line.
If you want to insert the file after each occurrence of the string TWO, then just use (as Shawn has already explained):
sed '/TWO/r extFile' baseFile

How to change file parmater by input in bash [duplicate]

This question already has answers here:
How do I use sed to change my configuration files, with flexible keys and values?
(8 answers)
Closed 2 years ago.
I have a file that contain this line
SELINUX = enforce
I want to change this by given input to permissive
How i do that without demage?
If [[ "$1" == "Y"]]
then
sed -ri 's/(^.*SELINUX=)(.*$)/\1enforce/' file
else
sed -ri 's/(^.*SELINUX=)(.*$)/\1permissive/' file
fi
If the first passed parameter ($1) is equal to "Y" use sed to split SELINUX line into to 2 sections. Substitute the line for the first section followed by "enforce". If the passed parameter is not "Y" substitute the line for the first section followed by "permissive".

How can I use sed or grep to delete the first line of input if it contains a string? [duplicate]

This question already has answers here:
How do I match multiple addresses in sed?
(4 answers)
Closed 3 years ago.
I am redirecting input and have 2 fields that I extracted from the tail of an XML file, and I need to ignore the first line if it isn't the first of the 2 entries.
tail -n 327 ~/.local/share/recently-used.xbel | grep -e "<bookmark href=" -e "<mime:mime-type type="
Here is the output from that code, which is working fine, but the problem is that the first line is a
<mime:mime-type type="application/x-shellscript"/>
<bookmark href="file:///usr/local/bin/menu_manager.sh" added="2019-09-17T08:33:48Z" modified="2019-09-17T08:33:48Z" visited="2019-09-17T08:33:49Z">
<mime:mime-type type="application/x-shellscript"/>
I need to look at the first line, and if it contains the string
<mime:mime-type type=
then I need to remove that line and pass the rest of the lines on for the next processing step
I tried
sed '1/<mime:mime-type/d'
But is gives me an error:
sed: -e expression #1, char 2: unknown command: `/'
Try
sed '1{/<mime:mime-type/d}'
which uses a block {} which is only run on line 1, with the delete command in the block.
If you are OK with awk you can use this
awk 'NR!=1 || !/<mime:mime-type type=/'
This prints every line that is not the first line (NR!=1) or doesn't match the pattern (!/<mime:mime-type type=/). As there is no action specified, awk uses the default action print.

How to Save 'specific' line from terminal output to file? [duplicate]

This question already has answers here:
Bash tool to get nth line from a file
(22 answers)
Closed 4 years ago.
I am currently using the following to save terminal outputs to file:
$command -someoptions >> output.txt
However, I am only interested in one line from the terminal output.
Is there a way to do this by changing the above expression. Or will I have to delete lines after the 'output.txt' file is formed?
For example: If my output is:
line 1
line 2
line 3
line 4
line 5
and all I want to save is:
line 4
where line 4 contains unknown information.
I am asking as I will later wish to script this command.
Many thanks,
Solution Found:
I ended up using:
$command -someoptions | sed -n '4p' >> output.txt
This is a classic simple grep issue.
$command -someoptions | grep 'line 4' >> output.txt
You could refine that with more pattern complexity, and might need it depending on how precisely you need to match the data.
Try with this command:
$command -someoptions | grep " filter " >> output.txt
filter must be replaced by an element that distinguishes your line 4 from the other lines.

Bash to merge 2 consecutive lines in a file [duplicate]

This question already has answers here:
how can I combine these lines
(4 answers)
Closed 8 years ago.
I want convert this text on a given file:
87665
S
3243423
S
334243
N
...
to something like this:
87665,S
3243423,S
334243,N
...
I've been reading some similar questions, but it didn't work... is there a way to do this with a single line command in linux?
Thanks!
Using sed:
sed '$!N;s/\n/,/' filename
Using paste:
paste -d, - - < filename
paste would leave a trailing , in case the input has an odd number of lines.
Something like this might work for you:
$ awk 'NR%2{a=$0;next}{print a","$0}' file
87665,S
3243423,S
334243,N
To handle files with odd lines, you can do:
awk '{printf "%s%s", $0, NR%2?",":ORS}' file
Just for fun, a pure bash solution:
while IFS= read -r l1; do
read -r l2
printf '%s\n' "$l1${l2:+,$l2}"
done < file
If there's an odd number of lines, the last line will not have a trailing comma.

Resources