update the first character of line if line contains two strings - linux

I am looking for a script to search a line if it contains two strings and then find if the first charater of that line contains certain character and remove it.
Eg. if line contains two strings as "abc" and "xyz" it should look for first character of the line and if it contains # , it should remove it and vice-versa.
It tried to run below command in crontab and got the result
crontab -l | grep az2-er32-cxv-iz| grep aze
Output
#5,10 * * * * /opt/apps/scripts/dsm-rync -q -del -s az2-er32-cxv-iz /opt/apps/sdl/scripts/aze-dsm-rync.app.config
since , its difficult to update the crontab entry directly , i copied it to tmpfile.
crontab -l > tmpfile and tried to run sed 's/^#//' tmpfile but it is removing all # instead of the line matching with two strings

You may use gnu awk to do this easily:
awk -i inplace '/az2-er32-cxv-iz/ && /aze/{sub(/^#/, "")} 1' crontab
This will remove # from first position if line has az2-er32-cxv-iz and aze in it.

As mentioned by Shloim, I won't give you the code itself, but I'm giving you a piece of pseudo-code to start:
In order to know if a line contains at least two words, you might search for a space within that line. (grep " " <filename>)
In order to know if a line starts with a certain character, you might search for the character, followed by that one certain character. (grep "<beginning_of_line>#")
Replacing a character in a line can be done, using the sed command.

Related

How to add character at the end of specific line in UNIX/LINUX?

Here is my input file. I want to add a character ":" into the end of lines that have ">" at the beginning of the line. I tried seq -i 's|$|:|' input.txt but ":" was added to all the ending of each line. It is also hard to call out specific line numbers because, in each of my input files, the line contains">" present in different line numbers. I want to run a loop for multiple files so it is useless.
>Pas_pyrG_2
AAAGTCACAATGGTTAAAATGGATCCTTATATTAATGTCGATCCAGGGACAATGAGCCCA
TTCCAGCATGGTGAAGTTTTTGTTACCGAAGATGGTGCAGAAACAGATCTGGATCTGGGT
>Pas_rpoB_4
CAAACTCACTATGGTCGTGTTTGTCCAATTGAAACTCCTGAAGGTCCAAACATTGGTTTG
ATCAACTCGCTTTCTGTATACGCAAAAGCGAATGACTTCGGTTTCTTGGAAACTCCATAC
CGCAAAGTTGTAGATGGTCGTGTAACTGATGATGTTGAATATTTATCTGCAATTGAAGAA
>Pas_cpn60_2
ATGAACCCAATGGATTTAAAACGCGGTATCGACATTGCAGTAAAAACTGTAGTTGAAAAT
ATCCGTTCTATTGCTAAACCAGCTGATGATTTCAAAGCAATTGAACAAGTAGGTTCAATC
TCTGCTAACTCTGATACTACTGTTGGTAAACTTATTGCTCAAGCAATGGAAAAAGTAGGT
AAAGAAGGCGTAATCACTGTAGAAGAAGGCTCAGGCTTCGAAGACGCATTAGACGTTGTA
Here is experted output file:
>Pas_pyrG_2:
AAAGTCACAATGGTTAAAATGGATCCTTATATTAATGTCGATCCAGGGACAATGAGCCCA
TTCCAGCATGGTGAAGTTTTTGTTACCGAAGATGGTGCAGAAACAGATCTGGATCTGGGT
>Pas_rpoB_4:
CAAACTCACTATGGTCGTGTTTGTCCAATTGAAACTCCTGAAGGTCCAAACATTGGTTTG
ATCAACTCGCTTTCTGTATACGCAAAAGCGAATGACTTCGGTTTCTTGGAAACTCCATAC
CGCAAAGTTGTAGATGGTCGTGTAACTGATGATGTTGAATATTTATCTGCAATTGAAGAA
>Pas_cpn60_2:
ATGAACCCAATGGATTTAAAACGCGGTATCGACATTGCAGTAAAAACTGTAGTTGAAAAT
ATCCGTTCTATTGCTAAACCAGCTGATGATTTCAAAGCAATTGAACAAGTAGGTTCAATC
TCTGCTAACTCTGATACTACTGTTGGTAAACTTATTGCTCAAGCAATGGAAAAAGTAGGT
AAAGAAGGCGTAATCACTGTAGAAGAAGGCTCAGGCTTCGAAGACGCATTAGACGTTGTA
Do seq have more option to modify or the other commands can solve this problem?
sed -i '/^>/ s/$/:/' input.txt
Search the lines of input for lines that match ^> (regex for "starts with the > character). Those that do substitute : for end-of-line (you got this part right).
/ slashes are the standard separator character in sed. If you wish to use different characters, be sure to pass -e or s|$|:| probably won't work. Since / characters, unlike | characters, are not meaningful character within the shell, it's best to use them unless the pattern also contains slashes, in which case things get unwieldy.
Be careful with sed -i. Make a backup - make sure you know what's changing by using diff to compare the files.
On OSX -i requires an argument.
Using ed to edit the file:
printf "%s\n" 'g/^>/s/$/:/' w | ed -s input.txt
For every line starting with >, add a colon to the end, and then write the changed file back to disk.

Replace text in a file in bash with / in the search string

How can i replace the following text in a file in linux with a different line
Current :
0 22 * * * /scripts/application_folder_backup.sh >> /var/log/application_folder_backup.log
Replacement line : #line_removed
I tried using sed but my text in the file already has a / which is causing problems. I tried storing the string in a variable too. But it doesn't work
#!/bin/bash
var="0 22 * * * /scripts/application_folder_backup.sh >> /var/log/application_folder_backup.log"
sed -i -e 's/$var/#line_removed/g' /tmp/k1.txt
exit
Just / is not a problem here, even * or all the special regex meta characters will be a problem for sed since it uses only regex for search patterns.
Better to use this non-regex based awk command:
awk -v var="$var" 'index($0, var) { $0 = "#line_removed" } 1' file
#line_removed
index function in awk uses plain text search instead of a regex based search.
I suggest previous to feed the contents of $var to the sed script, to escape all the / chars to be \/, as in:
var_esc=$(echo "$var" | sed 's/\//\\\//g')
But the sed expression gets very complicated (you must use single quotes, if you don't want to double \ chars, as double quotes do interpret also the backslashes.
Another thing that could simplify the expression is to use the possibility of change the regexp delimiter (with using a different char to begin it) as in:
var_esc=$(echo "$var" | sed 's:/:\/:g')
The idea is to, before substituting the $var variable, to escape all the possible interferring chars you can have (you don't know a priory if there are going to be, as you are using a variable for that purpose) and then substitute them in the final command:
sed "s/$var_esc/#line_removed/g"
Finally, if you don't want to substitute the line, but just to erase it, you can do something like this:
sed "/$var_esc/d"
and that will erase all lines that match your $var_esc contents. (this time I believe you cannot change the regexp delimiter, as the / introduces the matching line operator --- d is the command to delete line in the output)
Another way to delete the line in your file is to call ex directly and pass the editor command as input:
ex file <<EOF <-- edit "file" with the commands that follow until EOF is found.
/$var_esc <-- search for first occurrence of $var_esc
d <-- delete line
w <-- write file
EOF <-- eof marker.

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.

shell command delete line in text file with specific text in line

In looking for a command to delete a line (or lines) from a text file that contain a certain string.
For example
I have a text file as follows
Sat 21-12-2014,10.21,78%
Sat 21-12-2014,11.21,60%
Sun 22-12-2014,09.09,21%
I want to delete all lines that have "21-12-2014" in them.
I'm not able to find a solution that works.
According to #twalberg there is more three alternate solution for this question, which I'm explaining is as follows for future reader of this question for more versatile solutions:
With grep command
grep -v 21-12-2014 filename.txt
explanations:
-v is used to find non-matching lines
With awk command
awk '! /21-12-2014/' filename.txt
explanations:
! is denoting it will print all other lines that contain match of the string. It is not operator signify ignorance.
With sed command
sed -e '/21-12-2014/d' < filename.txt
explanations:
-e is signify scripted regex to be executed
d is denoting delete any match
< is redirecting the input file content to command
Try doing this :
sed -i.bak '/21-12-2014/d' *
A bit of explanations :
sed : the main command line, put the mouse pointer on sed
-i.bak : replace the file in place and make a backup in a .bak file
// is the regex
d means: delete

I'm having problems creating a sed script

My teacher didn't really go over sed scripts so they're very confusing. I need to finish this to get an A though. It's due very soon so I doubt I have time to fully understand it because I don't understand the syntax at all.
The instructions are:
Create a sed script named script3 that will print a file with “The Raven” at the top, replace every occurrence of multiple spaces with a single space, and print a line of 30 dashes below each line.
This is what I have so far:
sed script
echo "The Raven"
s/[ ]\{2,\}/ /g
/\,\./ s/^/------------------------------ /
Using the online GNU sed manual:
use the i command with an address to insert the title
use the a command with no address to append the separator after every line
use s/[[:blank:]]\+/ /g to replace any horizontal whitespace characters with a single space: sed regular expressions
enter code hereCreate a sed script named script3
so create a text file calles script3 taht is called with sed -f script3 YourSoureFile
content is
1 i\
The raven
s/ \{2,\}/ /g
a\
------------------------------
that will print a file with
“The Raven” at the top
1 i\
The raven
on 1st (1) line, insert (i) the next line (each line following until last cahr is NO NORE \
replace every occurrence of multiple spaces with a single space
s/ \{2,\}/ /g
substitute (s///) any pattern (part of text between the separator /composed of 2 or more \{2,\} following space jsute before the occurance specification, by a singel space the second , any occurence present ( option g). This happend at each line (no number or filter pattern in the head of the line like the 1 on precedent line)
and print a line of 30 dashes below each line
a\
------------------------------
(a) work like the (i) but append in this case. No filter pattern nor number indicate line to act, so on each line also.
i and a add text to ouptut but not on working buffer, so this cannot be manipulate inside this sed action, this is not the case of s/// that work ON the current working buffer (that is print at end of treatment of the line, before starting with a new line)
This is what I have so far:
About your script
echo "The Raven"
that is not a sed action but a shell action so, it cannot work in a sed like this (could using shell substitution but not the goal normaly)
s/[ ]\{2,\}/ /g
it's fine, class [] for this space is not necessary here but litterally ok. You could use [[:space:]] or [[:blank:]] or [[:space:][:blank:]] to be exhaustif using meta class of type [:xxxxx:] inside a class
/\,\./ s/^/------------------------------ /
this will mean *on each occurence of ,. (both and in this order), replace (add thus) the start of the line with 30 - and a space. So it's not occuring on each line and it add at the start not following the line. A way using s/// could be:
s/.*/&\
------------------------------/
Replace on each line every char (all at once) by herself (&) followed by a new line and 30 dash

Resources