Shell Script for Searching text with variable and replace it with content - shell

im new to shell script, but i need something to search a file with any given variable, and if the file contains this variable replace it with the variables alias
the text would be some thing like:
74304050 = +4574304050#voip1.local
74304051 = +4574304051#voip1.local
20304050 = +4520304050#voip2.local
20304051 = +4520304051#voip2.local
so if i use call the shell script with 20304050 i get +4520304050#voip1.local
how can this be done, i need it for calling aliases and rewriting them in opensips config file?

It's a bit underspecified, but does this do what you want?
awk -V number=20304050 '$1 == $number { print $3 }' file

Related

How do I save the output variable from terragrunt apply as regular shell environment variable?

After running my terragrunt apply-all in my CI step (so basically a bash script) I get my outputs, in this case I only have one:
output "cloudrun-hostname" {
value = google_cloud_run_service.cloudrun.status[0].url
description = "API endpoint URL"
}
How do I pass the value of that output to the environment variable so basically like I exported a variable like this:
export HOSTNAME=terragrunt-cloudrun-hostname-output
I need this variable with that value so I can envsub the value in another file later.
You can use the terraform output command, i.e.
export MY_ENV=$(terraform output cloudrun-hostname)
after your apply-all.
You will need to expand the command and so:
export HOSTNAME="$(terragrunt apply-all | awk -F= '/value/ { gsub(" ","",$2);print $2 }')"

extract xml using a variable in awk

I want search an XML file to extract specific XML block containing this string 58B338939C5B1970E1008000AC10E225_HCA_13
I am able to do it via the following command:
awk 'BEGIN{RS="<[/]?WorkResponseMessage>"} /58B338939C5B1970E1008000AC10E225_HCA_13/{print $0,"</WorkResponseMessage>"}' ag1.xml > ag2.xml
My query is I want to pass the search string in a variable from command line and use that variable to search, for example:
awk 'BEGIN{RS="<[/]?WorkResponseMessage>"} /$m/{print $0,"</WorkResponseMessage>"}' ag1.xml > ag2.xml
Here 'm' is my variable. I am able to get the value inside 'm', but it doesn't seem to work with the awk command. I have tried using quotes("",'') for m as well and that doesn't work either. The awk -v option also doesn't work with this
try this -
m="58B338939C5B1970E1008000AC10E225_HCA_13"
echo $m
awk -v m="$m" 'BEGIN{RS="<[/]?WorkResponseMessage>"} $0 ~ m {print $0,"</WorkResponseMessage>"}' ag1.xml > ag2.xml

how to find the position of a string in a file in unix shell script

Can you please help me solve this puzzle? I am trying to print the location of a string (i.e., line #) in a file, first to the std output, and then capture that value in a variable to be used later. The string is “my string”, the file name is “myFile” which is defined as follows:
this is first line
this is second line
this is my string on the third line
this is fourth line
the end
Now, when I use this command directly at the command prompt:
% awk ‘s=index($0, “my string”) { print “line=” NR, “position= ” s}’ myFile
I get exactly the result I want:
% line= 3, position= 9
My question is: if I define a variable VAR=”my string”, why can’t I get the same result when I do this:
% awk ‘s=index($0, $VAR) { print “line=” NR, “position= ” s}’ myFile
It just won’t work!! I even tried putting the $VAR in quotation marks, to no avail? I tried using VAR (without the $ sign), no luck. I tried everything I could possibly think of ... Am I missing something?
awk variables are not the same as shell variables. You need to define them with the -v flag
For example:
$ awk -v var="..." '$0~var{print NR}' file
will print the line number(s) of pattern matches. Or for your case with the index
$ awk -v var="$Var" 'p=index($0,var){print NR,p}' file
using all uppercase may not be good convention since you may accidentally overwrite other variables.
to capture the output into a shell variable
$ info=$(awk ...)
for multi line output assignment to shell array, you can do
$ values=( $(awk ...) ); echo ${values[0]}
however, if the output contains more than one field, it will be assigned it's own array index. You can change it with setting the IFS variable, such as
$ IFS=$(echo -en "\n\b"); values=( $(awk ...) )
which will capture the complete lines as the array values.

Adding file information to an AWK comparison

I'm using awk to perform a file comparison against a file listing in found.txt
while read line; do
awk 'FNR==NR{a[$1]++;next}$1 in a' $line compare.txt >> $CHECKFILE
done < found.txt
found.txt contains full path information to a number of files that may contain the data. While I am able to determine that data exists in both files and output that data to $CHECKFILE, I wanted to be able to put the line from found.txt (the filename) where the line was found.
In other words I end up with something like:
File " /xxxx/yyy/zzz/data.txt "contains the following lines in found.txt $line
just not sure how to get the /xxxx/yyy/zzz/data.txt information into the stream.
Appended for clarification:
The file found.txt contains the full path information to several files on the system
/path/to/data/directory1/file.txt
/path/to/data/directory2/file2.txt
/path/to/data/directory3/file3.txt
each of the files has a list of parameters that need to be checked for existence before appending additional information to them later in the script.
so for example, file.txt contains the following fields
parameter1 = true
parameter2 = false
...
parameter35 = true
the compare.txt file contains a number of parameters as well.
So if parameter35 (or any other parameter) shows up in one of the three files I get it's output dropped to the Checkfile.
Both of the scripts (yours and the one I posted) will give me that output but I would also like to echo in the line that is being read at that point in the loop. Sounds like I would just be able to somehow pipe it in, but my awk expertise is limited.
It's not really clear what you want but try this (no shell loop required):
awk '
ARGIND==1 { ARGV[ARGC] = $0; ARGC++; next }
ARGIND==2 { keys[$1]; next }
$1 in keys { print FILENAME, $1 }
' found.txt compare.txt > "$CHECKFILE"
ARGIND is gawk-specific, if you don't have it add FNR==1{ARGIND++}.
Pass the name into awk inside a variable like this:
awk -v file="$line" '{... print "File: " file }'

grep text by function parameter in bash

There is a file name as pkg_list
a-1.2b-1.tar.gz
c-2.5b-1.tar.gz
a xx-1.4.txz
a$xx-1.4.txz
中文-3.txz
xx-3.2-2.tar.gz
xxy-1.3.tar.gz
My bash function can input package name like 'xx'
pkg_find() { # <pkg_name> as $1
grep "^$1-[0-9]*" pkg_list
}
pkg_find xx # wish it return xx-3.2-2.tar.gz
I know I can not pass $1 directly into pkg_find, what's the correct method?
[SOLVED]
In this case, because $1 is enclosed by double quote, I found even regex meta chars could pass as parameter.
What you're doing looks right to me.
What isn't working?
I tried the code in your question, and pkg_find xx displays ‘xx-3.2-2.tar.gz’ — which you say is the output you were hoping for.
You can pass $1 directly to pkg_find
pkg_find() { # <pkg_name> as $1
grep "^$1-[0-9]*" pkg_list
}
pkg_find "$1"
In the main body, $1, $2, .. are the script arguments, you get from the command line or another calling script. In a shell function they refer to the function arguments.
When you call this on the command line
sh pkg_find.sh xx
you will get
xx-3.2-2.tar.gz
Your code and your question seem to me to ask for different things, you want to either/both of:
pass a function parameters: Passing parameters to a Bash function
return a string from a function: shell script function return a string
$1, $2 etc at the top-level of a script are the script parameters; within a function they
are set to the function parameters, or unset if there are no parameters.

Resources