sed replace a single line - bash

I am trying use sed to replace a single line.
Example:
space_left_action = EMAIL
admin_space_left_action = SUSPEND
I tried this command:
sed -i '/space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf
The result:
space_left_action = SYSLOG
space_left_action = SYSLOG
I do not want to replace the admin_space_left_action line, but still have the flexibility that if someone changes space_left_action value with something different sed will still replace the line.

use '^' for checking begining of line
sed -i '/^space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf

you also can try this
sed -i '/[^_]space_left_action*/c\space_left_action = SYSLOG' /etc/audit/auditd.conf

An awk version
awk '/^space_left_action/ {$3="SYSLOG"}1' /etc/audit/auditd.conf
space_left_action = SYSLOG
admin_space_left_action = SUSPEND

Related

Unmask data from matrix linux shell

i have 2 file.
analizeddata.txt:
A001->A002->A003->A004
A001->A005->A007
A022->A033
[...]
and
matrix.txt:
A001|Scott
A002|Bob
A003|Mark
A004|Jane
A005|Elion
A007|Brooke
A022|Meggie
A023|Tif
[..]
How i can replace in analizeddata.txt, or obtain a new file, with the second column of matrix.txt?
The expected output file will be as:
Scott->Bob->Mark->Jane
Scott->Elion->Brooke
Meggie->Tif
[...]
Thanks
Just use sed to replace the string what you want.
sed 's/|/\//g' matrix.txt will generate the replace pattern likes A001/Scott which will be used as regexp/replacement of the second sed s/regexp/replacement/ command.
sed -i option will update directly analizeddata.txt file, back up it before exec this command.
for replace_mode in $(sed 's/|/\//g' matrix.txt); do sed -i 's/'$replace_mode'/g' analizeddata.txt; done
Suggesting awk script:
awk -F"|" 'FNR==NR{arr[$1]=$2;next}{for(i in arr)gsub(i,arr[i])}1' matrix.txt analizeddata.txt
with provided sample data, results:
Scott->Bob->Mark->Jane
Scott->Elion->Brooke
Meggie->A033

BASH - Replace text in 'ini' file using variables

I'm expecting this to be an easy one for someone (alas not me!).
Using a bash script, I want to replace a value in a config file '/etc/app/app.cfg' (ini style), using variables for both search and replace.
The Value Name and Value I wish to update (note the space either side of the equals:
LOGDIR = /etc/app/logs
I have defined the following in the bash script:
# Get existing LogDir value
CURRENT_LOGDIR=$(grep 'LogDir =' /pathtofile | sed 's/LogDir *= *//g')
# Set New LogDir
LOGDIR=/mnt/eft/fs1/logs
# Update LogDir if different
if [[ -d $(echo $CURRENT_LOGDIR) != $LOGDIR ]] ; then
# Update LogDir value:
**bash command - I need help with !**
fi
I have tried many combinations with sed, to no avail, hence asking this question.
Things I've tried:
echo "LogDir = $LOGDIR" | sed '#s/$CURRENT_DIR/$LOGDIR/#g' /etc/app/app.cfg
sed -i '/#/!s/\(LogDir[[:space:]]*=[[:space:]]*\)\(.*\)/\1$LOGDIR#/g' /etc/app/app.cfg
sed -i 's/LogDir[[:space:]]=.*/LogDir = {LOGDIR}/' /etc/app/app.cfg
sed -i "s/^LogDir[[:space:]]*=.*/LogDir=$LOGDIR/}" /etc/app/app.cfg
sed -i '/#/!s/\(LogDir[[:space:]]*=[[:space:]]*\)\(.*\)/\1"$LOGDIR"/' /etc/app/app.cfg
Desired output:
Update LogDir value in /etc/app/app.cfg
For example:
LogDir = /mnt/eft/fs1/logs
What is that } doing on the end? Looks like a typo.
sed "s/^LogDir[[:space:]]*=.*/LogDir=$LOGDIR/" /etc/app/app.cfg
And sed edit file in place
Using sed
$ LOGDIR=/mnt/eft/fs1/logs
$ sed -i.bak "s|\([^=]*=[[:space:]]\).*|\1$LOGDIR|" /etc/app/app.cfg
$ cat /etc/app/app.cfg
LOGDIR = /mnt/eft/fs1/logs
How about this:
awk '$1 == "LogDir" {print "LogDir = /mnt/eft/fs1/logs"; next} {print}' old_configuration_file >new_configuration_file
The first awk clause replaces the old LogDir entry by the new one, and the second clause passes the other lines through unchanged.

How to remove a string from file in mac terminal

I have a file with million records and each line ends with SYSTEM;\N.
I want to delete all occurrences of ;\N from file. How can I approach this?
You can use the sed command to replace all the occurrences of the ';\N' from the file and replace it with ''.
sed -i 's/original/new/g' file.txt
Explanation:
sed = Stream EDitor
-i = in-place (i.e. save back to the original file)
The command string:
s = the substitute command
original = a regular expression describing the word to replace (or just the word itself)
new = the text to replace it with
g = global (i.e. replace all and not just the first occurrence)
file.txt = the file name
This worked finally sed -i '' 's/;\\N//g' test112.csv

ssh sed not changing variables correctly

I'm trying to use sed to change a variable in the site.js file on my server.
Here is the line: var url = "page.php"; I'm looking to just substitute page.php for whatever.php.
I thought this would be pretty simple and I figured this would work with no issues:
sed -i "s/\url = \".*\"/\url = \"page2.php\"/" /home/site.js
It works okay except instead of getting: var url = "page2.php"; I get: var R1 = "page2.php";
Why is the url value being changed to R1 when I use sed here?
You don't need \ before url.
sed -i -r 's#url\s*=\s*"[^"]+"#url = "page2.php"#' /home/site.js
Extra escaping of " can be eliminated by enclosing sed expression with ' instead of "
It's better to use different separator than / (here #) when the strings themselves may contain /
Try doing this :
sed -i -r 's#(var\s+url\s*=\s*")[^"]+"#\1whatever.php"#' file.js
/ is not mandatory as delimiter, I've picked up # there.
Here's another example: Took me while to figure that you change the / for delimiter and not the / in the directory path.
Use # instead of / for sed delimiter if you have dir path names.
First I tried this:
[root#ip-172-35-24-37 ec2-user]# egrep -q "^(\s*\S+\s+)/dev/shm(\s+\S+\s+\S+)(\s+\S+\s+\S+)(\s*#.*)?\s*$" /etc/fstab && sed -ri "s/^(\s*\S+\s+)/dev/shm(\s+\S+\s+\S+)(\s+\S+\s+\S+)(\s*#.*)?\s*$/\1/dev/shm\2nodev\3\4/" /etc/fstab
And got this error:
sed: -e expression #1, char 20: unknown option to `s'
So then I used # for the sed delimiter instead of /:
[root#ip-172-35-24-37 ec2-user]# egrep -q "^(\s*\S+\s+)/dev/shm(\s+\S+\s+\S+)(\s+\S+\s+\S+)(\s*#.*)?\s*$" /etc/fstab && sed -ri "s#^(\s*\S+\s+)/dev/shm(\s+\S+\s+\S+)(\s+\S+\s+\S+)(\s*#.*)?\s*$#\1/dev/shm\2nodev\3\4##" /etc/fstab
[root#ip-172-35-24-37 ec2-user]#
And it worked.
You can use something else besides # for a delimiter like ! or ? or %. Just don't use / if you have dir paths.

Escape UNIX character

This should be easy but i just can't get out of it:
I need to replace a piece of text in a .php file using the unix command-line.
using: sudo sed -i '' 's/STRING/REPLACEMENT/g' /file.php (The quotes after -i are needed because it runs on Mac Os X)
The string: ['password'] = ""; needs to be replaced by: ['password'] = "$PASS";
$PASS is a variable, so it gets filled in.
I got up to something like:
sudo sed -i '' 's/[\'password\'] = ""\;/[\'password\'] = "$PASS"\;/g' /file.php
But as i'm new with UNIX i don't know what to escape...
What should be changed? Thanks!
Unfortunately sed cannot robustly handle variables that might contain various characters that are "special" to sed and shell. You need to use awk for this, e.g. with GNU awk for gensub():
gawk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file
See how sed fails below when PASS contains a forward slash but awk doesn't care:
$ cat file
The string: ['password'] = ""; needs to be replaced
$ PASS='foo'
$ awk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file
The string: ['password'] = "foo"; needs to be replaced
$ sed "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" file
The string: ['password'] = "foo"; needs to be replaced
$ PASS='foo/bar'
$ awk -v pass="$PASS" '{$0=gensub(/(\[\047password\047] = \")/,"\\1"pass,"g")}1' file
The string: ['password'] = "foo/bar"; needs to be replaced
$ sed "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" file
sed: -e expression #1, char 38: unknown option to `s'
You need to use \047 or some other method (e.g. '"'"' if you prefer) to represent a single quote within an awk script that's single-quote-delimitted.
In awks without gensub() you just use gsub() instead:
awk -v pass="$PASS" '{pre="\\[\047password\047] = \""; gsub(pre,pre pass)}1' file
if you want to expand variable in sed, you have to use double quote, so something like
sed -i... "s/.../.../g" file
that is, you don't have to escape those single quotes, also you could use group reference to save some typing. you could try:
sudo sed -i '' "s/\(\['password'\] = \"\)\(\";\)/\1$PASS\2/g" /file.php

Resources