delete the last 2 characters from a text file: shell script - shell

I need to delete the last 2 characters from a text file in shell script.
Any idea about how I can do it?

Delete the last two characters on the last line only with sed:
$ sed '$s/..$//' file
If you are happy with changes then use -i to store them back to the file:
$ sed -i '$s/..$//' file
If you wanted to delete the last two characters on every line it would be:
$ sed 's/..$//' file
Again use -i to store the changes back to the file:
$ sed -i 's/..$//' file

Related

Delete all strings that do not contain any uppercase in Bash

I need to delete from a file all the words that do not contain any uppercase in bash.
I use the sed command but the output is the same as the input:
I tried sed 's/[^0-9]*//' file
Example input:
sjasd
ksaLK
asdn
Asdw
Output
ksaLK
Asdw
Could you please try following.
sed -n '/[A-Z]/p' Input_file
As per #PaulHodges's comment, once you are happy with results use sed -i .... option in above code to make changes in Input_file itself.
To make a file without those:
grep '[A-Z]' infile > outfile
This is a nondestructive way to check first. Then you could replace the old file with the new one.
If you really want to edit the existing file in place:
sed -i '/[A-Z]/!d' infile
This says to delete all lines that do not have a capital letter.

How to use sed and cat to add multi lines from one file to another

How can I use a cat and sed to read data from a file and insert it into another file under known line?
For example I have a file named script1.txt that contains a few hundred lines, one of the line has the value "COMMANDS="commands"
If I wanted use sed to insert a line under it, simply I can use sed as the command bellow.
sed -i '/^COMMANDS=.*/a NEW LINE HERE' script1.txt
But if I want to insert a multi lines and these lines inside a file, and these line changes every a few hours.. how can i do that ?
I tried:
DATA=$(cat data.txt)
sed -i '/^COMMANDS=.*/a '$DATA'' script1.txt
I got the error bellow.
sed: -e expression #1, char 1: unknown command: `"'
Is there a way other than sed to insert the data from file under known line with no issues?
This might work for you (GNU sed):
sed -i '/^COMMANDS=/r dataFile' file
This will append the contents of the file dataFile after the line beginning COMMANDS= and update file
If the data you want to append is multi-line, you might want to replace newlines with \n.
#!/bin/sh
DATA="$(awk '{gsub(/[]\/$*.^&[]/, "\\\\&");printf (FNR>1)?"\\n%s":"%s",$0}END{print ""}' data.txt)"
sed -i -e '/^COMMANDS=.*/a\' -e "$DATA" script1.txt
Here the awk command escapes sed special characters (for basic regular expressions), then prints "%s" for the first line, and "\\n%s" for the others. A newline is printed at the end, but it's somewhat pointless as $() strips it anyway.
The sed command is almost the same but multiple expressions are used which is equivalent to a multi-line sed script (The a text sed alternative syntax can act weirdly with leading spaces/backslashes).

how to remove both first and last line of csv file using sed

I can remove the first line of csv file's starting with myfile and merge them using:
sed 1d myfile*.csv > myfile_merged.csv
I'd like to also remove the last line of the csv files.
I've tried:
sed 1d -i '$d' myfile*.csv > myfile_merged.csv
But get the error:
sed: can't read $d: No such file or directory
Problem is this command:
sed 1d -i '$d' myfile*.csv > myfile_merged.csv
You need not have an argument after -i (inline replacement) in sed otherwise it is treated as a SUFFIX to create a backup for inline replacement.
What you need is this gnu sed command:
sed -i '1d;$d' myfile*.csv
This will remove 1st and last line in each of the matched file and save it in place.
What you're probably trying to do is:
sed -e '1d' -e '$d' myfile*.csv > merged.csv
But this won't work, because it tells sed to remove the first and last line of ALL files, rather than EACH file. In other words, you'll strip the first line of the first file, and the last line of the last file ... and that's it.
To process each file individually, you probably need to process each file .. individually. :)
for f in myfile*.csv
sed -e '1d;$d' "$f"
done > merged.csv
Note that while this will run in bash, it's also POSIX compatible (both the shell and sed parts). And it does not care whether your input is CSV or any other format, as long as it can be parsed line by line using sed.

Shell script - How do I insert data into a separate file at a specific line?

In the following shell script, how do I insert ${today} into a separate existing file index.html at line 4? (Line 1-3 in index.html already has some code. Line 4 is empty. Line 5-EOL has some html code.)
#!/bin/sh
Today=$(date "+%Y.%m.%d-%H.%M.%S")
#insert ${today} into a separate existing file (index.html) in line 4
#<to-do>
I'd use awk for this:
awk 'NR==4 {print strftime("%Y.%m.%d-%H.%M.%S", systime())} 1' file
You can also pass in a variable if you don't want to generate the date string inside awk:
Today=$(date "+%Y.%m.%d-%H.%M.%S")
awk -vtoday=$Today 'NR==4 {print today} 1' file
The sed utility can insert text at specific lines. This might not be the best way to express it; it overwrites anything it finds on line 4.
Today=$(date "+%Y.%m.%d-%H.%M.%S")
sed -i -e "4s/^.*$/$Today/" index.html
The -i argument tells sed to edit in place--it effectively overwrites the input file. I think this option makes sed a better choice than awk for your problem. For testing, remove the -i argument, and it will write to stdout instead.
If you want this to work only if line 4 is a blank line (no whitespace, no characters), use this instead.
Today=$(date "+%Y.%m.%d-%H.%M.%S")
sed -i -e "4s/^$/$Today/" index.html

replace a string in file using shell script

Suppose my file a.conf is as following
Include /1
Include /2
Include /3
I want to replace "Include /2" with a new line, I write the code in .sh file :
line="Include /2"
rep=""
sed -e "s/${line}/${rep}/g" /root/new_scripts/a.conf
But after running the sh file, It give me the following error
sed: -e expression #1, char 14: unknown option to `s'
If you are using a newer version of sed you can use -i to read from and write to the same file. Using -i you can specify a file extension so a backup will be made, incase something went wrong. Also you don't need to use the -e flag unless you are using multiple commands
sed -i.bak "s/${line}/${rep}/g" /root/new_scripts/a.conf
I have just noticed that as the variables you are using are quoted strings you may want to use single quotes around your sed expression. Also your string contains a forward slash, to avoid any errors you can use a different delimiter in your sed command (the delimiter doesn't need to be a slash):
sed -i.bak 's|${line}|${rep}|g' /root/new_scripts/a.conf
You have to write the changes to a new file and then, move the new file over the old one. Like this:
line="Include 2"
rep=""
sed -e "s/${line}/${rep}/g" /root/new_scripts/a.conf > /root/new_scripts/a.conf-new
mv /root/new_scripts/a.conf-new /root/new_scripts/a.conf
The redirection (> /root/new_scripts/a.conf) wipes the contents of the file before sed can see it.
You need to pass the -i option to sed to edit the file in-place:
sed -i "s/${line}/${rep}/g" /root/new_scripts/a.conf
You can also ask sed to create a backup of the original file:
sed -i.bak "s/${line}/${rep}/g" /root/new_scripts/a.conf
So, if you have to replace a substring in a file, you can use sed command like this, say we have a file as file.txt, so replacing a substring in it can be done like this
searchString="abc";
replaceString="def";
sed -i '' "s|$searchString|$replaceString|g" file.txt
This will all the occurrences of "abc" with "def" in file.txt. Also, this keeps a check for any / character present in the variables used, and with no backup file made.

Resources