Replace a line with a number if part of it is matches using sed - linux

I know this is a very simple question and been discussed many times, but I can't understand where I am doing wrong in my command.
I would like to replace the lines which starts with "It" as 99999. Each row starts with several blank spaces.
infile.txt
3
2
3
4
It is not a number = /home/kayan/data
3
5
It is not a number = /home/kayan/data
4
5
I used
sed -i 's/^I/99999/g' infile.txt
But it is not working.

Due to starting space, add it to pattern search
sed -i 's/^[[:blank:]]*I.*/99999/' infile.txt
using the change function
sed -i '/^[[:blank:]]*I/ c\
9999' infile.txt
keeping starting space
sed -i 's/^\([[:blank:]]*\)I.*/\199999/' infile.txt
No need of the g, there is only 1 change per line possible

give this a try:
sed -i 's/^\s*It.*/9999/'

What you are replacing there is just the ^I part, i.e. the first letter. Use ^I.* instead to match the whole remaining line and it also gets replaced.

Related

Sed/AWK search/replace string after every matched pattern

I have data in variable like json -
v={k1:v1,k2:v2,k3:v3,k4:v4,k5:v5,k6:v6,k7:v7,k8:v8};
where key and value could be any values.
I need to split this into multiple lines after every 10 character..which i did by
echo "${v}" | sed -r 's/.{10}/&\n/g'
This does the split as per sed . But now i need to make sure split should happen only after comma character found after every 10 characters...so that out put should have meaningful lines ..
output should be ..
k1:v1,k2:v2,
.....
Whole idea is not break lines in between
Thanks
You may use
sed -r 's/.{10}[^,]*,/&\n/g'
See the sed demo online.
The .{10}[^,]*, pattern matches
.{10} - any 10 chars
[^,]* - 0 or more chars other than ,
, - a comma.
The &\n replacement pattern replaces with the whole match (&) and appends a newline to it.
If actually you just want to add a newline after every 2nd comma then that's this in GNU sed and some other seds:
$ echo "$v" | sed 's/,[^,]*,/&\n/g'
k1:v1,k2:v2,
k3:v3,k4:v4,
k5:v5,k6:v6,
k7:v7,k8:v8
or this for portability across all seds in all shells:
sed 's/,[^,]*,/&\
/g'
or this using any awk:
awk '{gsub(/,[^,]*,/,"&\n")}1'
Sorry and thanks for feed back here is the expected output-
{k1:v1,k2:v2,
k3:v3,k4:v4,
k5:v5,k6:v6,
k7:v7,k8:v8}
Rule should be look for first 10 characters then first comma when found add a new line after that pattern.
Wiktor code snippt does this actually. However , i am happy to see to achieve this with other ways. Thanks all.

Conditional replace using sed

My question is probably rather simple. I'm trying to replace sequences of strings that are at the beginning of lines in a file. For example, I would like to replace any instance of the pattern "GN" with "N" or "WR" with "R", but only if they are the first 2 characters of that line. For example, if I had a file with the following content:
WRONG
RIGHT
GNOME
I would like to transform this file to give
RONG
RIGHT
NOME
I know i can use the following to replace any instance of the above example;
sed -i 's/GN/N/g' file.txt
sed -i 's/WR/R/g' file.txt
The issue is that I want this to happen only if the above patterns are the first 2 characters in any given line. Possibly an IF statement, although i'm not sure what the condition would look like. Any pointers in the right direction would be much appreciated, thanks.
just add the circumflex, remove g suffix (unnecessary, since you want at most one replacement), you can also combine them in one script.
sed -i 's/^GN/N/;s/^WR/R/' file.txt
Use the start-of-string regexp anchor ^:
sed -i 's/^GN/N/' file.txt
sed -i 's/^WR/R/' file.txt
Since sed is line-oriented, start-of-string == start-of-line.

How to remove blank space between some words using sed?

I want to replace characters between specific words in a line (multiple lines). for example:
first second third | first line
first second third | second line
first second third | third line
first second third | forth line
....
I want to replace characters between third and first/second/third/forth etc...using sed or vi in linux.
If this question is already answered, can you please provide me the link?
Thanks!
You can use the following:
sed 's/ |.[^a-z]*//g' text.txt
or if you want to have a space after 'third':
sed 's/ |.[^a-z]*/ /g' text.txt
remember about the -i flag to make permanent changes.
sed -i 's/\ /whatever/g' ej.txt
-i: in file, means that changes are made directly in the file
-s: substitute
-'\ ': to recognize blank space
-g: all matches on each line
Try this
sed 's/second third[^a-zA-Z]*/second third/g' file
It will replace everything between third and this first letter. And if it works use -i if you want to modify the original file

How to delete 5 lines before and 6 lines after pattern match using Sed?

I want to search for a pattern "xxxx" in a file and delete 5 lines before this pattern and 6 lines after this match. How can i do this using Sed?
This might work for you (GNU sed):
sed ':a;N;s/\n/&/5;Ta;/xxxx/!{P;D};:b;N;s/\n/&/11;Tb;d' file
Keep a rolling window of 5 lines and on encountering the specified string add 6 more (11 in total) and delete.
N.B. This is a barebones solution and will most probably need tailoring to your specific needs. Questions such as: what if there are multiple string throughout the file? What if the string is within the first five lines or multiple strings are within five lines of each other etc etc etc.
Here's one way you could do it using awk. I assume that you also want to delete the line itself and that the file is small enough to fit into memory:
awk '{a[NR]=$0}/xxxx/{f=NR}END{for(i=1;i<=NR;++i)if(i<f-5||i>f+6)print a[i]}' file
Store every line into the array a. When the pattern /xxxx/ is matched, save the line number. After the whole file has been processed, loop through the array, only printing the lines you want to keep.
Alternatively, you can use grep to obtain the line number first:
grep -n 'xxxx' file | awk -F: 'NR==FNR{f=$1}NR<f-5||NR>f+6' - file
In both cases, the lines deleted will be surrounding the last line where the pattern is matched.
A third option would be to use grep to obtain the line number then use sed to delete the lines:
line=$(grep -nm1 'xxxx' file | cut -d: -f1)
sed "$((line-5)),$((line+6))d" file
In this case I've also added the -m switch so grep exits after finding the first match.
if you know, the line number (what is not difficult to obtain), you can use something like that:
filename="test"
start=`expr $curr_line - 5`
end=`expr $curr_line + 6`
sed "${start},${end}d" $filename (optionally sed -i)
of course, you have to remember about additional conditions like start shouldn't be less than 1 and end greater than number of lines in file.
Another - maybe more easy to follow - solution would be to use grep to find the keyword and the corresponding line:
grep -n 'KEYWORD' <file>
then use sed to get the line number only like this:
grep -n 'KEYWORD' <file> | sed 's/:.*//'
Now that you have the line number simply use sed like this:
sed -i "$(LINE_START),$(LINE_END) d" <file>
to remove lines before and/or after! With only the -i you will override the <file> (no backup).
A script example could be:
#!/bin/bash
KEYWORD=$1
LINES_BEFORE=$2
LINES_AFTER=$3
FILE=$4
LINE_NO=$(grep -n $KEYWORD $FILE | sed 's/:.*//' )
echo "Keyword found in line: $LINE_NO"
LINE_START=$(($LINE_NO-$LINES_BEFORE))
LINE_END=$(($LINE_NO+$LINES_AFTER))
echo "Deleting lines $LINE_START to $LINE_END!"
sed -i "$LINE_START,$LINE_END d" $FILE
Please note that this will work only if the keyword is found once! Adapt the script to your needs!

How to remove words from a file in UNIX?

first file of information page
name/joe/salary1 50 10 2
name/don/miles2
20 4 3
name/sam/lb3 0 200 50
can some one please tell me how can I remove all the words in the above file, so my output will looks as follows
50 10 2
20 4 3
0 200 50
Use awk instead. The following code says to go through each field, check if its an integer. If it is, print them out. No need complicated regex.
$ awk '{for(i=1;i<=NF;i++) if($i+0==$i) {printf $i" "} print ""}' file
50 10 2
20 4 3
0 200 50
sed -e "s/[a-zA-Z/]/ /g" file
will do it, though I like codaddict's way more if you want to preserver number and whitespace. This way strips out all letters and the '/' symbol, replacing them all with space.
If you want to modify the file in place, pass the -i switch. This command will output what the file would look like.
Looks like you want to preserve only the digits and the space. If yes, you can do:
sed 's/[^0-9 ]//g' inputFile
EDIT: Change in requirements, if a digit is found with a letter, it should be treated as part of the word.
This Perl script does it:
perl -ne 's/(?:\d*[a-z\/]+\d*)*//g;print' input
If your file has this structure, I suggest first to filter out the first line, then remove all characters from beginning of line up to the first space:
sed -ni '2,$s/^[^ ]*//p' file
Remove everything on each line until first space character (also removes leading spaces):
sed 's/\S*\s*//' file

Resources