How to read config files with section in bash shell
To use --exclude-from
you will have to isolate the relevant section of the config into a temporary file. This is easy to do with a bit of sed:
tmp_file=$(mktemp)
sed -n '1,/rsync_exclude/d;/\[/,$d;/^$/d;p' config.file > $tmp_file
rsync -avz --exclude-from $tmp_file source/ destination/
I am omitting error checking and cleanup for clarity.
Note that rsync can read the exclude pattern from the stdin for an -
input, so this is even shorter:
sed -n '1,/rsync_exclude/d;/\[/,$d;/^$/d;p' config.file | \
rsync -avz --exclude-from - source/ destination/
Explanation
- The
1,/rsync_exclude/d
excludes all lines up to the rsync_exclude section entry - The
/\[/,$d
excludes everything from the start of the next section to the end of the file - The
/^$/d
excludes empty lines (this is optional)
All of the above extracts the relevant section from the config.
Parsing variables from config file in Bash
awk -F\= '{gsub(/"/,"",$2);print "Content of " $1 " is " $2}' <filename>
Just FYI, another pure bash solution
IFS="="
while read -r name value
do
echo "Content of $name is ${value//\"/}"
done < filename
bash reading and writing a config file with an unusual layout
For the first question, pre-process your .cfg
file and then read it, like this:
CONFIG_FILE=test.cfg
sed 's/ = /=/g' < test.cfg > /tmp/processed.cfg
. /tmp/processed.cfg
Now, all your name_1
, name_2
pairs will be available to your shell scripts.
For the second question, do it like this:
CONFIG_FILE=test.cfg
TARGET_KEY='name_1 '
REPLACEMENT_VALUE='"true" '
sed -i -e "s/\($TARGET_KEY *= *\).*/\1$REPLACEMENT_VALUE/" $CONFIG_FILE
Reading a config file from a shell script
You don't want source it, so you should:
1.read the config, 2.verify lines 3.eval them
CONFIGFILE="/path/to/config"
echo "=$ADMIN= =$TODO= =$FILE=" #these variables are not defined here
eval $(sed '/:/!d;/^ *#/d;s/:/ /;' < "$CONFIGFILE" | while read -r key val
do
#verify here
#...
str="$key='$val'"
echo "$str"
done)
echo =$ADMIN= =$TODO= =$FILE= #here are defined
sample of config file
ADMIN: root
TODO: delete
var=badly_formtatted_line_without_colon
#comment
FILE: /path/to/file
if you run the above sample should get (not tested):
== == ==
=root= =delete= =/path/to/file=
sure this is not the best solution - maybe someone post a nicer one.
Edit a configuration file with sections using bash
Your current attempt has some problems.
# Your code
sed -i "s/^\s*($1\s*\).*\$/\1$2/" $3
After $1
you want at least one whitespace (you don't want to match key2), use '+'.
You would like the keep first whitespace(s) after the replacement, put it in the match.
Maybe you get additional spaces after a short key, so put the spaces after the key in the match too.
You don't want to match $
. With the backslash it is a character. You don't need to match end-of-line, the .*
will match everything until end-of-line.
How about a config file with a space in its name? Quote $3
.
And the \s
doesn't work in plain sed
. Try -r
.
I deleted the -i
, so you can test without changing the file:
sed -r "s/^(\s*$1\s+).*$/\1$2/" "$3"
When you want to limit this code to a section, use /start/,/end/
. How do you know something is a header? In your example the header lines are called header, but that will not be the case in your real config file. When the headers look like [section]
, change the solution beneath. The solution beneat assumes that all lines that don't start with whitespace is a header.
# Set a configuration value
# Args:
# 1) The config key
# 2) The new value
# 3) The config section header
# 4) The config file
function set_config_value() {
key="$1"
val="$2"
header="$3"
file="$4"
# first test this without the -i flag
sed -ir "/^${header}$/,/^[^\s]/ s/^(\s*${key}\s+).*$/\1${val}/" "${file}"
}
This solution should work for your sample config, but will fail when ${key}
or ${value}
has a special character (try key=/
).
You should use a solution that doesn't try to understand the strings given. My first thought would be awk
, but make your own choice. Look at https://unix.stackexchange.com/q/137643/57293 .
how to parse a config file (*.conf) in shell script?
I'd do this:
pw=$(awk '/^password/{print $3}' app.conf)
user=$(awk '/^user/{print $3}' app.conf)
echo $pw
root123
echo $user
root
The $()
sets the variable pw
to the output of the command inside. The command inside looks through your app.conf file for a line starting password
and then prints the 3rd field in that line.
EDITED
If you are going to parse a bunch of values out of your config file, I would make a variable for the config file name:
CONFIG=app.conf
pw=$(awk '/^password/{print $3}' "${CONFIG}")
user=$(awk '/^user/{print $3}' "${CONFIG}")
Here's how to do the two different ports... by setting a flag to 1 when you come to the right section and exiting when you find the port.
mport=$(awk '/^\[MySQL\]/{f=1} f==1&&/^port/{print $3;exit}' "${CONFIG}")
sport=$(awk '/^\[Server\]/{f=1} f==1&&/^port/{print $3;exit}' "${CONFIG}")
bash: how to source array from section config file after sed?
source
requires a file for an argument. Thus, replace:
source $(sed -n '1,/animals/d;/\[/,$d;/^$/d;p;' config)
With:
source <(sed -n '1,/animals/d;/\[/,$d;/^$/d;p;' config)
The bash construct <(...)
is called process substitution. It creates a file-like object that source
can read from. It is in contrast to $(...)
which is called command substitution which creates a string.
Related Topics
Libpcap - Capture Packets from All Interfaces
Certificate with Extended Key Usage Only Works in Firefox
Process Stuck in Exit, Shows as Zombie But Cannot Be Reaped
How to Add Boost Library to Code::Blocks in Linux
Sending Keycode to Xorg + Wine with Bash Script
How to Add an User and Re Set the Root User in Yocto
How Uevents Get Triggered in Kernel
How to Capitalize First Letter of Each Line in Bash
Shell Script for Process Monitoring
How to Count Number of Executed Instructions of a Process Id Including All Future Child Threads
Find Value from One CSV in Another One (Like Vlookup) in Bash (Linux)
(Delphi Linux) Ld-Linux.Exe: Error: Cannot Find -Lgcc_S
What Does Two Dots Before a Slash Mean? (../)
Capturing Display/Monitor Images, Sending Keyboard Input on Linux