linux bash tool to read property from property file [duplicate] - linux

This question already has answers here:
How to grep for contents after pattern?
(8 answers)
Closed 6 years ago.
I want to be able to run a command to get a property from a property file. So if my properties file is property.props and has
username=dsollen
password=letMeIn
linux-skills=newb
I would like to have a quick way to pull out the property to pipe into other commands. so
./myProgram -v -p `getProp property.props password`
or something like that; not sure I used the ` right, but that's a different newb linux question for later :)
I know I can do this with a combination of grep and cut/awk/sed/whatever, but I'm wondering if there is an already existing tool that 'knows' how to read common property file formats and does something like this? If not I could write something to add into my scripts folder, just don't want to reinvent the wheel if a better wheel already exists.

You can use gvar to do the work. I'm the author by the way.
From the source code, this is the interesting part for you:
get_variable() {
< "$FILE" grep -w "$1" | cut -d'=' -f2
}

I assume your properties keys are unique, if so then the following might be a way:
grep -w "$1" <property.props
or to get the value
(grep -w "$1" | cut -d= -f2) <property.props
Where $1 is the key.

Look, just define in your .bashrc a function:
getProp() {
awk -F "=" "/^$2=/ {print "'$2'"; exit; }" $1
}
And use it in your shell:
$ getProp property.pros password
letMeIn
$ getProp property.pros linux-skills
newb

Related

Piping into a part of bash command stored in variable [duplicate]

This question already has answers here:
Conditional step in a pipeline
(2 answers)
Can I make a shell function in as a pipeline conditionally "disappear", without using cat?
(1 answer)
Closed 4 months ago.
EMPTY_VAR=''
MMDDYYYY='6.18.1997'
PIPE_VAR=' | xargs echo "1+" | bc'
echo "$MMDDYYYY" | cut -d "." -f 2${EMPTY_VAR}
>> 18
Command above would give me correct output, which is 18, but if I try to use PIPE_VAR instead it would give me bunch of errors:
echo "$MMDDYYYY" | cut -d "." -f 2${PIPE_VAR}
cut: '|': No such file or directory
cut: xargs: No such file or directory
cut: echo: No such file or directory
cut: '"1+"': No such file or directory
cut: '|': No such file or directory
cut: bc: No such file or directory
OR:
echo "$MMDDYYYY" | cut -d "." -f 2"$PIPE_VAR"
cut: invalid field value ‘| xargs echo "1+" | bc’
Try 'cut --help' for more information.
What I'm really trying to find out is that even possible to combine commands like this?
You can't put control operators like | in a variable, at least not without resorting to something like eval. Syntax parsing comes before parameter expansion when evaluating the command line, so Bash is only ever going to see that | as a literal character and not pipeline syntax. See BashParsing for more details.
Conditionally adding a pipeline is hard to do well, but having a part of the pipeline conditionally execute one command or another is more straightforward. It might look something like this:
#!/bin/bash
MMDDYYYY='6.18.1997'
echo "$MMDDYYYY" | cut -d "." -f 2 |
if some_conditional_command ; then
xargs echo "1+" | bc
else
cat
fi
It looks like you're trying to calculate the next day. That's hard to do with plain arithmetic, particularly with month/year ends.
Let date do the work. This is GNU date. It can't parse 6.18.1997 but it can parse 6/18/1997
for MMDDYYYY in '2.28.1996' '2.28.1997'; do
date_with_slashes=${MMDDYYYY//./\/}
next_day=$(date -d "$date_with_slashes + 1 day" '+%-m.%-d.%Y')
echo "$next_day"
done
2.29.1996
3.1.1997

Bash how to loop through the output of a command and assign that output to variable [duplicate]

This question already has answers here:
Looping through the content of a file in Bash
(16 answers)
Closed 11 months ago.
I have a for loop in my bash script.
for dir in $directories
do
dockerfile=$(find ./repo/$dir -name "Dockerfile");
docker build -f $dockerfile . -t $dir:version;
new_image=$(echo "$dir:version" | cut -d '/' -f2);
done
How can I pass $new_image output to another variable?
If I do something like this
new_image=$(echo "$image:version" | cut -d '/' -f2 >> list_images.txt)
I get the list of docker images in my .txt file but is there a way to pass the output to a variable? And update that variable value on each iteration?
The expected output after one iteration is something like
testing1:version
So when the for loop stops executing I get something like this in my .txt file.
testing1:version
kubernetes:version
node:version
And this is what I need, I can't figure out a better way to do this.
Using an answer, because the comments make it unreadable.
Do I understand correctly that you want:
for dir in $directories
do
dockerfile=$(find ./repo/$dir -name "Dockerfile");
docker build -f $dockerfile . -t $dir:version;
echo "$dir:version" | cut -d '/' -f2
done > list_images.txt
or do you actually have a need for the variable(s) further-on in your script?
And
new_image=$(echo "$dir:version")
trimmed=${new_image#*/}
will do your cut in bash, but that's just for bonuspoints :-)

How to extract a value of a key from a long string with sed? [duplicate]

This question already has answers here:
Can I use sed to manipulate a variable in bash?
(3 answers)
Closed 4 years ago.
I have a long string and from that string I want to extract a value of a key and store it in a variable. I want to extract value of userName from abc string. I tried below code but it say's file name too long error.
abc="Create [newSystem=System [identityDomain=bbundlesystemser201201-test, admin=AdminUser [firstName=BSystemAdminGivenName, middleName=null, lastName=BSystemAdminFalilyName, userName=bbundlesystemadminusername, password=*******, email=hello#example.com], idmConsoleURL=https://abc.com.jspx, sftpHost=d910.abc.com, sftpUser=3pyylzoo, sftpPwd=*******]]"
echo $abc
sed -n 's/^userName= //p' "$abc"
Is there anything wrong I am doing? I want to extract value of userName and store it in a variable.
userName=bbundlesystemadminusername
You can use BASH regex matching:
[[ $abc =~ userName=([^][,[:space:]]+) ]] && userName="${BASH_REMATCH[1]}"
echo "$userName"
bbundlesystemadminusername
Or else, you can use this sed command:
userName=$(sed 's/.*userName=\([^][,[:space:]]*\).*/\1/' <<< "$abc")
I think I'd do this with an associative array and process substitution in bash 4:
$ declare -A a
$ while IFS== read k v; do a["$k"]="$v"; done < <(grep -oEi '[a-z]+=[^], ]+' <<<"$abc")
$ printf '%q\n' "${a[userName]}"
bbundlesystemadminusername
While this doesn't properly respect the data structure of your input variable, it does recognize key=value pairs and save them in an easily accessible array, using only a single grep -o to split the string into the KV pairs. The nice this about this is of course that you've got the rest of the data also available to you, should you want to avoid unnecessary calls to grep or awk or sed or whatever.
Note that associative arrays were added to bash in version 4. If you're doing this in macOS (or indeed in a POSIX shell), it'll have to be adjusted.

"Command not found" piping a variable to cut when output stored in a variable [duplicate]

This question already has answers here:
How to pass the value of a variable to the standard input of a command?
(9 answers)
Closed 5 years ago.
In a bash script I am using a variable to hold a path like this:
MY_DIR=/just/a/string/to/my/path
And I want to remove the last two parts of it so it looks like this:
/just/a/string
I am using 'cut' to do it, like this:
echo $MY_DIR | cut -d'/' -f-4
The output is what I expect. Fine.
But I want to store in an other variable, like this:
MY_DIR2=$($MY_DIR | cut -d'/' -f-4)
When I execute the script I get the error:
... /just/a/string/to/my/path: No such file or directory
Why is the direct output with echo working, but storing the output in a variable is not?
You need to pass an input string to the shell command using a pipeline in which case cut or any standard shell commands, reads from stdin and acts on it. Some of the ways you can do this are use a pipe-line
dir2=$(echo "$MY_DIR" | cut -d'/' -f-4)
(or) use a here-string which is a shell built-in instead of launching a external shell process
dir2=$(cut -d'/' -f-4 <<< "$MY_DIR")
Use the grave accent(`) to emulate a command, and use echo too.
MY_DIR2=`echo $MY_DIR | cut -d'/' -f-4`

Extract just file path from string

I have a file that contains strings in this format:
MD5 (TestImages/IMG_0627.JPG) = 6ed611b3e777c5f7b729fa2f2412d656
I am trying to figure out a way to extract the file path, so that I would get a string like this:
TestImages/IMG_0627.JPG
For a different part of my script, I am using this code to remove everything before and after the brackets, and I could of course do something similar, however I'm sure there is a better way?
shortFile=${line#*MD5 }
shortFile=${shortFile%%)*}
Anyone have any suggestions?
You could use sed but that has the overhead of starting a new process.
echo $line | sed -r 's/MD5 \((.*)\).*/\1/'
Just to throw a non-sed answer onto the pile. (Also slightly cheaper since it avoids the pipeline and sub-shell.)
awk -F '[()]' '{print $2}' <<<"$line"
That said the substring expansion option is a reasonable one if it does what you need. (Though it looks like you missed the ( in the first expansion.)
Another way with cut can be :
echo $line|cut -d "(" -f2|cut -d ")" -f1
sed -e 's/^.*(\([^)]*\)).*$/\1/' < infile.txt

Resources