sed,awk.grep - add a line to the end of a configuration section if the line doesn't already exist
Using awk
:
awk '
$0 == "SECTION 2 BEGIN" { inSec2 = 1 }
inSec2 && $0 == "important line" { hasImportant = 1 }
inSec2 && $0 == "SECTION END" {
if (!hasImportant) { print "important line" }
inSec2 = 0
}
1'
Change a configuration variable or add it if it does not exist using sed/awk/grep
You can replace sed
bu this awk
:
awk '/^PermitRootLogin/ {
found=1;
sub(/^PermitRootLogin[[:blank:]]+.*$/, "PermitRootLogin no")
}
1;
END {
if (!found)
print "PermitRootLogin no"
}' file
Appending a line to a file only if it does not already exist
Just keep it simple :)
grep + echo should suffice:
grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
-q
be quiet-x
match the whole line-F
pattern is a plain string- https://linux.die.net/man/1/grep
Edit:
incorporated @cerin and @thijs-wouters suggestions.
sed add line if not exists
The easiest way would be to test before using grep
, for example:
grep -q -e 'extension=solr.so' file || sed '...'
Also, it is estrange that you need exactly that line. You should add it at the end, or something like that.
Also, note that taking the same file as input and output never should be done. This can damage the file badly. You should be using the -i
sed parameter to do in-place editing.
Add a line to a file section unless it exists
line=$(grep "$SOME_PATH" %ldirs)
if [ $? -eq 1 ]
then
echo "$SOME_PATH" >> %ldirs
fi
something like this should work, it worked fine for me. I'm sure there are other ways to write it, too.
line=$(grep "$SOME_PATH" /path/to/file)
if [ $? -eq 1 ]
then
sed -i 's/%lsdir/%lsdir\n"$SOME_PATH"/' /path/to/file
fi
should work. It'll find %lsdir and replace it with %lsdir(newline)$SOME_PATH (not sure if quotes are needed on $SOME_PATH here, pretty sure they aren't)
Optimize a multi-utility command to a single-utility command
Try the following (you could turn it into a one-liner, if desired):
awk '
FNR==1 { blankCount = inSection = count = 0 } # initialize vars. for every file
/^#+ Usage #/ { inSection=1; next } # section start, set flag
inSection && /^#+/ { print count; nextfile } # section end, print result, proceed to next file
inSection { # a line inside the section of interest
if (NF == 0) { ++blankCount; next } # a blank line, count it and skip
if (blankCount == 2) { count+=NF } # a line after the 2nd blank one, count its words
}
' file # supports multiple input files
Note:
The code assumes that there are at least 3 blank lines in each section and that the words / non-blank lines between the 2nd blank line and the 3rd one or the end of the section (whichever comes first) should be counted.
With the sample input, the result is6
.The code counts words (whitespace-separated fields, reflected in
NF
, the number of fields) rather than lines, but since your input only has one word per line, the line count (which is what yourwc -l
command does) is the same as the word count.
Related Topics
Cmsg_Nxthdr() Returns Null Even Though There Are More Cmsghdr Objects
How to Suspend and Resume a Sequence of Commands in Bash
Serialport in Mono in Linux Not Responding to Datareceived Event
Gatttool Non-Interactive Mode --Char-Write
Differentiate Between Exit and Session Timeout
Django on Apache Wtih Mod_Wsgi (Linux) - 403 Forbidden
Unusual Behaviour of Linux's Sort Command
Replace Bash Variables in Template File
Usb Modem Is Echoing Back Wrong Characters
Multiple -A with Greater Than/Less Than Break Bash Script
Overhead of Supporting Floating Point Arithmetic Inside the Linux Kernel
Bash - Concatenating Variable on to Path
How to Run Ionic in the Background
Extracting Variable in Yaml from a Shell Script
Arm: Disabling Mmu and Updating Pc
Stack Smashing Code Not Working on Linux Kernel 2.6.38.7... Please Help