How to print a character using Shell script - bash

Below is my script that acquire the MAC of the machine and store within a config file.
My problem is that within each line have the character " " and it dont print it inside the file, how can I write the file using " "
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
echo "
view.sslVerificationMode = *3*
view.autoConnectDesktop = *TRUE*
view.autoConnectBroker = *TRUE*
view.kioskLogin = *TRUE*
view.nonInteractive = *TRUE*
view.fullScreen = *TRUE*
view.nomenubar = *TRUE*
view.defaultBroker = *viewcs*
view.defaultUser = *CM-${MAC//:/_}*
" > /etc/vmware/view-mandatory-config;
sed -i 's/*/"/g' /etc/vmware/view-mandatory-config

with cat and a here-doc you can use multi-line input without escaping charaters
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
cat << EOT > /etc/vmware/view-mandatory-config
view.sslVerificationMode = "3"
view.autoConnectDesktop = "TRUE"
view.autoConnectBroker = "TRUE"
view.kioskLogin = "TRUE"
view.nonInteractive = "TRUE"
view.fullScreen = "TRUE"
view.nomenubar = "TRUE"
view.defaultBroker = "viewcs"
view.defaultUser = "CM-${MAC//:/_}"
EOT
cat will relay the stdin input generated by the here document to stdout, thus enabling redirection to a file

Simply escape double-quotes within the outer double-quotes by putting a backslash in front of them:
MAC=$(ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
echo "
view.sslVerificationMode = \"3\"
view.autoConnectDesktop = \"TRUE\"
view.autoConnectBroker = \"TRUE\"
view.kioskLogin = \"TRUE\"
view.nonInteractive = \"TRUE\"
view.fullScreen = \"TRUE\"
view.nomenubar = \"TRUE\"
view.defaultBroker = \"viewcs\"
view.defaultUser = \"CM-${MAC//:/_}\"
" > /etc/vmware/view-mandatory-config

Related

what is this line means $runCmd = "cmexec $node1 echo \"\" > ".$logfile;

Code snippet:
my $node = shift;
my $runCmd = "cmviewcl -v -f line -p ".$package_name." | awk -F \"[:|=]\" \'(\$1 == \"script_log_file\") { print \$2 }\'";
my $logfile = $output[0];
chomp $logfile;
#DC1_list = utils::getDC1Host($hash_ref);
#DC2_list = utils::getDC2Host($hash_ref);
foreach $node1 (#DC1_list) {
$runCmd = "cmexec $node1 echo \"\" > ".$logfile;
Please let me know the what's this line means:
$runCmd = "cmexec $node1 echo \"\" > ".$logfile;
it was written before as:
$runCmd = "cmexec $node1 rm -rf ".$logfile;
which probably means remove the file in logfile variable forced recursive, but later changed to the above. so
what's it's doing?
Remove a file is different than an empty file.
The first option keep the file but override the content with "" (2x double quote), the second one remove the file.
Maybe your application need the file exist, because of this you cannot remove it.
If you have really copied this line verbatim, it is pretty nonsense.
Let's assume that the variables mentioned here have the folllowing values:
runCmd has value FOO
node1 has value BAR
logfile has value BAZ
After parameter expansion and making the quoting a bit more legible, this leaves you with a line equivalent to
FOO = 'cmexec BAR echo "" >' .BAZ
This means that a command named FOO is invoked. It must either be an executable file in the PATH, or a function. This command gets three parameters:
First parameter : a lonely equal sign
Second parameter: The string cmexec BAR echo "" >
Third paramete : the string .BAZ
I don't believe that anybody would seriously write such a command; my guess is that you made a typo, or error when doing a copy&paste of this command.

extracting vdate form nc header with bash without opening file

I have to change the title of a couple of hundred files by adding the vdate from its header to its title.
If vdate = 19971222, then I want the name of that nc file to become rerun4_spindown_19971222.nc
I know I can find the vdate by ncdump -h filename (see example header below).
ncdump -h rerun4_1997_spindown_09191414_co2
netcdf rerun4_1997_spindown_09191414_co2 {
dimensions:
lon = 768 ;
lat = 384 ;
nhgl = 192 ;
nlevp1 = 96 ;
spc = 32896 ;
// global attributes:
:file_type = "Restart history file" ;
:source_type = "IEEE" ;
:history = "" ;
:user = " Linda" ;
:created = " Date - 20190919 Time - 134447" ;
:label_1 = " Atmospheric model " ;
:label_2 = " Library 23-Feb-2012" ;
:label_3 = " Lin & Rood ADVECTION is default" ;
:label_4 = " Modified physics" ;
:label_5 = " Modified radiation" ;
:label_6 = " Date - 20190919 Time - 134447" ;
:label_7 = " Linda " ;
:label_8 = " Linux " ;
:fdate = 19950110 ;
:ftime = 0 ;
:vdate = 19971222 ;
:vtime = 235800 ;
:nstep = 776158 ;
:timestep = 120. ;
However, then I have to manually open all the files and manually change the title of the file... of hundreds of files. I would prefer making a bash that can automatically do that.
I am sure there must be a more intelligent way to extract the vdate from the nc header, could you guys help me out?
Thank you!
In theory, something like that should work:
#! /bin/sh
for file in rerun4_*_spindown_* ; do
vdate=$(ncdump -h $file | awk '$1 == ":vdate" { print $3 }')
new_name="rerun4_spindown_$vdate.nc"
mv "$file" "$new_name"
done
I do not have access to netCDF files - more testing is needed.

integer-only wildcards in grep

i have command that outputs a collection strings that look like this:
json.formats[0]].url = "https://example.com/ar.html"
json.formats[1].url = "https://example.com/es.html"
json.formats[2s].url = "https://example.com/ru.html"
json.formats[3].url = "https://example.com/pt.html"
json.formats[73].url = "https://example.com/ko.html"
json.formats[1502].url = "https://example.com/pl.html"
(there are many more instances, however for simpilcity's sake theyve been removed)
i can use the command below
myCmd | grep -e 'json\.formats\[.*\]\.url\ \=\ '
however i only want the wildcard to match integers, and to throw out non-integer matches. it gives me the following:
json.formats[0]].url = "https://example.com/ar.html"
json.formats[1].url = "https://example.com/es.html"
json.formats[2s].url = "https://example.com/ru.html"
json.formats[3].url = "https://example.com/pt.html"
json.formats[73].url = "https://example.com/ko.html"
json.formats[1502].url = "https://example.com/pl.html"
what i really want is this:
json.formats[1].url = "https://example.com/es.html"
json.formats[3].url = "https://example.com/pt.html"
json.formats[73].url = "https://example.com/ko.html"
json.formats[1502].url = "https://example.com/pl.html"
Thanks :-)
You may use:
myCmd | grep -E 'json\.formats\[[[:digit:]]+\]\.url = '
or:
myCmd | grep -E 'json\.formats\[[0-9]+\]\.url = '
[[:digit:]] is equivalent of [0-9] for most of the locales.

replace string in class bash and azuredevops (ios xamarin pipeline)

I am trying to write a bash script to change a string in a class for my azure devops pipeline.But cannot make it work.
Copied the script from
https://github.com/Microsoft/appcenter-build-scripts-examples/blob/master/xamarin/app-constants/appcenter-pre-build.sh
my bash attempt:
Added a bash task (inline script)
Created an env variable API_URL with value ="https://production.com/api"
My Class to change
namespace Core
{
public class AppConstant
{
public const string ApiUrl = "https://production.com/api";
public const string AnotherOne="AAA";
}
}
My script
if [ ! -n "$API_URL" ]
then
echo "You need define the API_URL variable"
exit
fi
APP_CONSTANT_FILE=$(Build.SourcesDirectory)/MyProject/Core/AppConstant.cs
if [ -e "$APP_CONSTANT_FILE" ]
then
echo "Updating ApiUrl to $API_URL in AppConstant.cs"
sed -i '' 's#ApiUrl = "[a-z:./]*"#ApiUrl = "'$API_URL'"#' $APP_CONSTANT_FILE
echo "File content:"
cat $APP_CONSTANT_FILE
fi
why does my variable not change? many thanks
Your script is correct and will get desired output, only remove the dual apostrophes after sed -i:
sed -i 's#ApiUrl = "[a-z:./]*"#ApiUrl = "'$API_URL'"#' $APP_CONSTANT_FILE
However I would also change regexp at least to this, since . (dot) is reserved as any character in regexp:
sed -i 's#ApiUrl = "[a-z:\./]*"#ApiUrl = "'$API_URL'"#' $APP_CONSTANT_FILE
Or even to this (in order to take whatever characters between quotes):
sed -i 's#ApiUrl = "[^"]*"#ApiUrl = "'$API_URL'"#' $APP_CONSTANT_FILE
Test:
$ cat > developer9969.txt
namespace Core
{
public class AppConstant
{
public const string ApiUrl = "https://production.com/api";
}
}
API_URL='https://kubator.com/'
APP_CONSTANT_FILE='./developer9969.txt'
sed -i 's#ApiUrl = "[^"]*"#ApiUrl = "'$API_URL'"#' $APP_CONSTANT_FILE
$ cat $APP_CONSTANT_FILE
namespace Core
{
public class AppConstant
{
public const string ApiUrl = "https://kubator.com/";
}
}

Network Monitor: Don't Show Same Line Immediately Twice [duplicate]

I am writing a network monitoring script in bash. The base command I am using is ettercap -T -M ARP -i en1 // //. Then I pipe egrep --color 'Host:|GET' into it.
A sample output I am getting looks like this:
GET /images/srpr/logo11w.png HTTP/1.1.
Host: www.google.com.
GET /en-us/us/products HTTP/1.1.
Host: www.caselogic.com.
My desired output is this:
Title: logo11w.png
URL: www.google.com/images/srpr/logo11w.png HTTP/1.1.
Title: Products - Case Logic
URL: www.caselogic.com/en-us/us/products
Things to notice: HTTP/1.1. and the . at the end of the host are gone. They also are formed into one URL and there is a blank line after each Title/URL listing. I attempted forming them into one URL by parsing the commands output into a variable with
var=`sudo ettercap -T -M ARP -i en1 // // | egrep --color 'Host:|GET'` | echo $var
but obviously that doesn't work because the input to the variable is a command the isn't done until the user requests a stop (CTRL + C).
To get the title of an HTML page, I use the command wget -qO- 'https://url.goes/here' | perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'. If it is something that doesn't have a title, such as an image, no title is fine.
Any help is greatly appreciated, and sorry if what I wrote is hard to read, feel free to ask questions.
Try this:
title_host.pl
#!/usr/bin/env perl
use warnings;
use strict;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
my ($get,$host,$title);
while (<>) {
if (m|^GET (\S+) |) {
$get = $1;
} elsif ( m|^Host: (\S+)\.| ) {
$host = $1;
} else {
# Unrecognized line...reset
$get = $host = $title = '';
}
if ($get and $host) {
my ($title) = $get =~ m|^.*\/(.+?)$|; # default title
my $url = 'http://' . $host . $get;
$mech->get($url);
if ($mech->success) {
# HTML may have title, images will not
$title = $mech->title() || $title;
}
print "Title: $title\n";
print "URL: $url\n";
print "\n";
$get = $host = $title = '';
}
}
input
GET /images/srpr/logo11w.png HTTP/1.1.
Host: www.google.com.
GET /en-us/us/products HTTP/1.1.
Host: www.caselogic.com.
now just pipe your input into the perl script:
cat input | perl title_host.pl
output:
Title: logo11w.png
URL: http://www.google.com/images/srpr/logo11w.png
Title: Products - Case Logic
URL: https://www.caselogic.com/en-us/us/products

Resources