Bash script for replacing texts - linux

I have a file.txt file as in the following example:
Part 1
Some texts #abc d#ae}gd1 l2#4.
Part 2
Some texts again #efd de#gm}dg 12#a.
I want "#" is replaced by "hi" in the whole file, however in part 2 I also want to put the part from # up to the first character that's not in 0-9A-Za-z inside "check{ }".
So this is the output:
Part 1
Some texts hiabc dhiae}gd1 l2hi4.
Part 2
Some texts again check{hiefd} decheck{higm}}dg 12check{hia}.
I only knew how to replace # by "hi" in the whole:
awk '{gsub(/#/,"hi")} 1' file.txt > output.txt ;
It's really difficult for me to find a way to handle the requirement in part 2.
Thank for any help.
I wanted to find a solution for this.

This sed command should do the trick:
sed '/Part 1/,/Part 2/s/#/hi/g
/Part 2/,$s/#\([0-9A-Za-z]*\)/check{hi\1}/g
' file

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.

How can replace a specific line in a text file with a shell script?

I am trying to replace a specific line in a txt file with my shell script, for example;
cat aa.txt:
auditd=0
bladeServerSlot=0
When I run my script I would like to change "bladeServerSlot" to 12 as following;
cat aa.txt:
auditd=0
bladeServerSlot=12
Could you please help me?
Using sed and backreferencing:
sed -r '/bladeServerSlot/ s/(^.*)(=.*)/\1=12/g' inputfile
Using awk , this will search for the line which contains bladeServerSlot and replace the second column of that line.
awk 'BEGIN{FS=OFS="="}/bladeServerSlot/{$2=12}1' inputfile
perl -pe 's/bladeServerSlot=\K\d+/12/' aa.txt > output.txt
The \K is a particular form of the positive lookbehind, which discards all previous matches. So we need to replace only what follows. The s/ is applied by default to $_, which contains the current line. The -p prints $_ for every line, so all other lines are copied. We redirect output to a file.
Is it really necessary to replace the line in your example? As bladeServerSlot is a variable you could reset the value.
bladeServerSlot=`any command`
Or you could just let this variable be filled by a Parameter provided to this script.
bladeServerSlot=$1
With $1being the first parameter of your script. I think this would be the cleaner way do solve your issue than to do fancy regex here. The sed/perl solutions will work, but they are not very clear to other people reading your script.

How to delete a string with the same word and consecutively increasing number in a text file using a shell script?

For example I have:
Hello1 :
Hello2 :
Hello3 :
How Could I delete all of these with a shell script. The number reaches up all the way to 1000.
sed -i '/^Hello[[:digit:]]\+\>/d' file.txt
Or, if you want to output to a different file:
sed '/^Hello[[:digit:]]\+\>/d' file.txt > newfile.txt
If you wish to delete all the lines that contain only Hello(number) : use below :
Sample Input in file
Hell
Hello1 :
No hello stuff here
Unjulating stuff
Hello2 :
Some sentence
Hello99 :
Script
sed -Ei '/^Hello[[:digit:]]+ :$/d' file
Sample Output in the modified file
Hell
No hello stuff here
Unjulating stuff
Some sentence
What happens above
Using the ^ in the pattern we check for the beginning of the line.
We check the pattern Hello(number) : using Hello[[:digit:]]+ :$. Note that I used -E to enable sed extended regular expressions so I need not escape the + ie (\+). Here [[:digit:]] is a class which contains
all the decimal digits and + is used to check if the pattern before it matches at least one time.
Check the end of the line using $
For a matched pattern, delete it line using the d option
I have also used the sed inplace edit option -i so that the changes
are directly saved to the file.
If you wish to change the a line the begins with Hello(number) : then use the below script
sed -Ei '/^Hello[[:digit:]]+ :/d' file
You might have notices that I just removed the $, so our pattern matches any line that starts with Hello(number) :
Hope this helps.

Is there a way to put the following logic into a grep command?

For example suppose I have the following piece of data
ABC,3,4
,,ExtraInfo
,,MoreInfo
XYZ,6,7
,,XyzInfo
,,MoreXyz
ABC,1,2
,,ABCInfo
,,MoreABC
It's trivial to get grep to extract the ABC lines. However if I want to also grab the following lines to produce this output
ABC,3,4
,,ExtraInfo
,,MoreInfo
ABC,1,2
,,ABCInfo
,,MoreABC
Can this be done using grep and standard shell scripting?
Edit: Just to clarify there could be a variable number of lines in between. The logic would be to keep printing while the first column of the CSV is empty.
grep -A 2 {Your regex} will output the two lines following the found strings.
Update:
Since you specified that it could be any number of lines, this would not be possible as grep focuses on matching on a single line see the following questions:
How can I search for a multiline pattern in a file?
Regex (grep) for multi-line search needed
Why can't i match the pattern in this case?
Selecting text spanning multiple lines using grep and regular expressions
You can use this, although a bit hackity due to the grep at the end of the pipeline to mute out anything that does not start with 'A' or ',':
$ sed -n '/^ABC/,/^[^,]/p' yourfile.txt| grep -v '^[^A,]'
Edit: A less hackity way is to use awk:
$ awk '/^ABC/ { want = 1 } !/^ABC/ && !/^,/ { want = 0 } { if (want) print }' f.txt
You can understand what it does if you read out loud the pattern and the thing in the braces.
The manpage has explanations for the options, of which you want to look at -A under Context Line Control.

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