Change a letter in a file to uppercase in Shell script - linux

I'm trying to change a specific given letter to uppercase in a file, but I don't know how to do it. The file already exist and I want to do the following
cat merry.txt
I wish you a Merry Christmas
Change e to E so the output will be
cat merry.txt
I wish you a MErry Christmas
Thank you everyone

Try this :
sed 's/e/E/' merry.txt
If your text included more than one occurrence of ā€eā€ on a line, the preceding sed would
have changed just the first occurrence on each line to ā€E.ā€ By appending the global option
g to the end of the s command, you can ensure that multiple occurrences of the string on a line will be changed.
Try to use this :
sed 's/e/E/g' merry.txt
This command converts all e to E.
Or can use :
sed -i 's/e/E/g' merry.txt

Like this:
sed 's/e/\Ue/' Input_File
To edit permanently, add -i switch:
sed -i ...

You can use tr to "translate" a char to another char:
tr 'e' 'E' < file > newfile && mv newfile file
You can also use awk (here, a dynamic approach is used):
find='e'
replace='E'
awk -v f="$find" -v r="$replace" '{gsub(f, r)}1' file > newfile && mv newfile file
With GNU sed, you may use
sed -i 'y/e/E/' file
In all these case, you replace an e with E everywhere in the file and save the contents of the updated file under the same filename.
See a sample demo online:
#!/bin/bash
s='I wish them a Merry Christmas'
find='e'
replace='E'
tr "$find" "$replace" <<< "$s"
awk -v f="$find" -v r="$replace" '{gsub(f, r)}1' <<< "$s"
sed 'y/e/E/' <<< "$s"
Output: I wish thEm a MErry Christmas.

Related

How to replace string into numbers using sed?

I am trying to replace string into number from the file
So, I have variable &FLOW which need to change to 001, ex :
cat file.txt
This is file ' PISP &FLOW'
PISD.DATA.CYCLE&FLOW..ONE
desired output
This is file ' PISP 001'
PISD.DATA.CYCLE001.ONE
I tried below commands in a script :
for item in file.txt
do
sed 's/\&FLOW/\./001/g' $item
sed 's/\&FLOW/001/g' $item
done
It is giving error. The second sed command is working, but I need to run first the beginning sed command otherwise after running first the second sed command, it would ignore the beginning sed command.
Any help would be appreciated!
Use a single sed command and use -i to actually modify the file contents and you need to pass file.txt as the input for the sed command:
sed -i 's/&FLOW\.\{0,1\}/001/g' file.txt
See the online demo. If you are using it in Mac OS, you need sed -i '' 's/&FLOW\.\{0,1\}/001/g' file.txt. Also see sed edit file in place.
Pattern details
It is a POSIX BRE compliant pattern matching
&FLOW - a literal &FLOW substring
\.\{0,1\} - 0 or 1 occurrence of a . char.
try this:
for item in file.txt
do
sed 's/\&FLOW\./001/g' $item
sed 's/\&FLOW/001/g' $item
done
You had a redundant / in after FLOW
This might also work:
sed -i 's/\&FLOW[\.]?/001/g' file.txt

How to generate a UUID for each line in a file using AWK or SED?

I need to append a UUID ( newly generated unique for each line) to each line of a file. I would prefer to use SED or AWK for this activity and take advantage of UUIDGEN executable on my linux box. I cannot figure out how to generate the the UUID for each line and append it.
I have tried:
awk '{print system(uuidgen) $1} myfile.csv
sed -i -- 's/^/$(uuidgen)/g' myfile.csv
And many other variations that didn't work. Can this be done with SED or AWK, or should I be investigating another solution that is not shell script based?
Sincerely,
Stephen.
Using bash, this will create a file outfile.txt with a concatenated uuid:
NOTE: Please run which bash to verify the location of your copy of bash on your system. It may not be located in the same location used in the script below.
#!/usr/local/bin/bash
while IFS= read -r line
do
uuid=$(uuidgen)
echo "$line $uuid" >> outfile.txt
done < myfile.txt
myfile.txt:
john,doe
mary,jane
albert,ellis
bob,glob
fig,newton
outfile.txt
john,doe 46fb31a2-6bc5-4303-9783-85844a4a6583
mary,jane a14bb565-eea0-47cd-a999-90f84cc8e1e5
albert,ellis cfab6e8b-00e7-420b-8fe9-f7655801c91c
bob,glob 63a32fd1-3092-4a72-8c24-7b01c400820c
fig,newton 63d38ad9-5553-46a4-9f24-2e19035cc40d
Just tweaking the syntax on your attempt, something like this should work:
awk '("uuidgen" | getline uuid) > 0 {print uuid, $0} {close("uuidgen")}' myfile.csv
For example:
$ cat file
a
b
c
$ awk '("uuidgen" | getline uuid) > 0 {print uuid, $0} {close("uuidgen")}' file
52a75bc9-e632-4258-bbc6-c944ff51727a a
24c97c41-d0f4-4cc6-b0c9-81b6d89c5b77 b
76de9987-a60f-4e3b-ba5e-ae976ab53c7b c
The right solution is to use other shell commands though since the awk isn't buying you anything:
$ xargs -n 1 printf "%s %s\n" $(uuidgen) < file
763ed28c-453f-47f4-9b1b-b2f972b2cc7d a
763ed28c-453f-47f4-9b1b-b2f972b2cc7d b
763ed28c-453f-47f4-9b1b-b2f972b2cc7d c
Try this
awk '{ "uuidgen" |& getline u; print u, $1}' myfile.csv
if you want to append instead of prepend change the order of print.
Using xargs is simpler here:
paste -d " " myfile.csv <(xargs -I {} uuidgen {} < myfile.csv)
This will call uuidgen for each line of myfile.csv
You can use paste and GNU sed:
paste <(sed 's/.*/uuidgen/e' file) file
This uses the GNU execute extension e to generate a UUID per line, then paste pastes the text back together. Use the -d paste flag to change the delimiter from the default tab, to whatever you want.

How to to delete a line given with a variable in sed?

I am attempting to use sed to delete a line, read from user input, from a file whose name is stored in a variable. Right now all sed does is print the line and nothing else.
This is a code snippet of the command I am using:
FILE="/home/devosion/scripts/files/todo.db"
read DELETELINE
sed -e "$DELETELINE"'d' "$FILE"
Is there something I am missing here?
Edit: Switching out the -e option with -i fixed my woes!
You need to delimit the search.
#!/bin/bash
read -r Line
sed "/$Line/d" file
Will delete any line containing the typed input.
Bear in mind that sed matches on regex though and any special characters will be seen as such.
For example searching for 1* will actually delete lines containing any number of 1's not an actual 1 and a star.
Also bear in mind that when the variable expands, it cannot contain the delimiters or the command will break or have unexpexted results.
For example if "$Line" contained "/hello" then the sed command will fail with
sed: -e expression #1, char 4: extra characters after command.
You can either escape the / in this case or use different delimiters.
Personally i would use awk for this
awk -vLine="$Line" '!index($0,Line)' file
Which searches for an exact string and has none of the drawbacks of the sed command.
You might have success with grep instead of sed
read -p "Enter a regex to remove lines: " filter
grep -v "$filter" "$file"
Storing in-place is a little more work:
tmp=$(mktemp)
grep -v "$filter" "$file" > "$tmp" && mv "$tmp" "$file"
or, with sponge (apt install moreutils)
grep -v "$filter" "$file" | sponge "$file"
Note: try to get out of the habit of using ALLCAPSVARS: one day you'll accidentally use PATH=... and then wonder why your script is broken.
I found this, it allows for a range deletion with variables:
#!/bin/bash
lastline=$(whatever you need to do to find the last line)` //or any variation
lines="1,$lastline"
sed -i "$lines"'d' yourfile
keeps it all one util.
Please try this :
sed -i "${DELETELINE}d" $FILE

Bash - Add blank line above line starting with a period

I need to edit a text file by adding a blank line above every line starting with a period.
Before
Corn
.Apple
Words.
.Orange
Bean
After
Corn
.Apple
Words.
.Orange
Bean
Here is what I have so far.
This adds a spaces after every period. There are more in the actual file.
cat File.txt | sed -r 's/([.]+)/\n\1/g'
This displays the lines that start with a period
while read -r line; do
if [[ "$line" == "."* ]]; then
echo "$line"
fi
done < File.txt
How do I merge them together?
This produces the output that you want:
$ sed 's/^[.]/\n./' file
Corn
.Apple
Words.
.Orange
Bean
If you want to change the file in-place, use sed's -i option:
sed -i 's/^[.]/\n./' file
For Mac OSX or other BSD system, use:
sed -i '' 's/^[.]/\n./' file
We use ^ which matches only at the beginning of a line. Since we are matching a period at the beginning of the line, it is not necessary to capture a group with parentheses: we know the match is a period. All that we need to do is add a newline before that period.
with sed
sed 's/^\./\n\./'
with awk
awk '/^\./{print ""} 1'
or
awk 'sub(/^\./,"\n.") 1'
Using RegExp it could be:
cat File.txt | sed -r 's/^(\..+)/\n\1/g'
I think an awk script is going to work best.
/^\./ {print "";}
{print $0;}
Put that into a file, in this case, called "awkfile" and run it like `awk -f awkfile File.txt'
$ sed -e '/^\./i\\' pru.txt
Corn
.Apple
Words.
.Orange
Bean
this command line instructs sed(1) to search for lines beginning with a dot, and then insert a blank line before it. Look in sed(1) manual page for how to use the insert, replace and append commands.

How to delete lines from file with sed\awk?

I have file, with lines, contains ip with netmask
a.b.c.d/24
w.x.y.z/32
etc
How to delete delete specific row?
i'm using
sed -ie "s#a.b.c.d/24##g" %filname%
but after the removal is an empty string in file.
It should run inside a script, with ip as parameter and also work in freebsd under sh.
Sed solution
sed -i '/<pattern-to-match-with-proper-escape>/d' data.txt
-i option will change the original file.
Awk solution
awk '!/<pattern-to-match-with-proper-escape>/' data.txt
Using sed:
sed -i '\|a.b.c.d/24|d' file
Command line arg:
For the input being command line argument, say 1st argument($1):
sed -i "\|$1|d" file
Replace $1 with appropriate argument number as is your case.
You should use d (delete) not g. Also do not use s (replacement).
sed -ie '/a.b.c.d\/24/d' %filename%
In a script you should using it in this way
IP=$1
IPA=${IP////\\/}
sed -i /"${IPA}"/d %filename%
And the script parameter should be called in this way:
./script.sh a.b.c.d/24
perl -i -lne 'print unless(/a.b.c.d\/24/)' your_file
or in awk if you donot want to do inplace editing:
awk '$0!~/a.b.c.d\/24/' your_file

Resources