Import file to script and fill variables inside the file - linux

I have script import.sh
. properties
sql=$(cat sql.sql)
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
${sql}
${dbname} > ${log_file} 2>> ${log_file}
and file properties
psql_path="/usr/pgsql-9.6/bin"
dbname="postgres"
path="/opt/files"
log_file="ok.log"
and file sql.sql
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
i need to run psql command with importing lines from file sql.sql on the line ${sql} in script import.sh but including text /opt/files instead of the variable itself ${path}, eg:
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '/opt/files/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '/opt/files/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}
edit: all im getting right now is example below. How do i insert the text of variable ${path} ?
${psql_path}/psql \
-X \
--set ON_ERROR_STOP=on \
--set AUTOCOMMIT=on \
--echo-all \
-c "truncate table SCHEMA.TABLE1;" \
-c "\\copy SCHEMA.TABLE1 FROM '${path}/TABLE1.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
-c "truncate table SCHEMA.TABLE2;" \
-c "\\copy SCHEMA.TABLE2 FROM '${path}/TABLE2.tsv' DELIMITER ';' CSV HEADER ENCODING 'UTF8' QUOTE '\"'" \
${dbname} > ${log_file} 2>> ${log_file}

This line:
sql=$(cat sql.sql)
Will put contents of "sql.sql" into this variable $sql but won't evaluate any variables inside it. The right way to do this is to use a heredoc, instead. But since I figure out you want to keep your script, a simple solution would be:
sql=$(cat sql.sql | sed -e 's#${path}#'"${path}"'#')
This is simple running sed to substitute the contents of "${path}" into the contents of shell variable of the same name. But anyway consider using heredocs, because your "sql" file is obviously not SQL at all.

As advised, the HEREDOC is the best option and then simple parameter substitution can be done:
. properties
sql=$(cat sql.sql)
${psql_path}/psql <<-EOF
-X
--set ON_ERROR_STOP=on
--set AUTOCOMMIT=on
--echo-all
${sql//\$\{path\}/$path}
${dbname} > ${log_file} 2>> ${log_file}
EOF
Notice too that the line extensions are no longer required either. You should be able to remove them from sql.sql file as well

Related

cat EOF keeps indenting and interprets variables

use 'EOF',it can keep indenting, but it can't explain variables
[root#master ~]# registry=10.105.100.4/library
[root#master ~]# cat > /etc/sysconfig/kubelet << 'EOF'
> KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
> --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
> --feature-gates=LocalStorageCapacityIsolation=true \
> --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --eviction-hard=memory.available<500Mi,nodefs.available<10% \
> --max-pods=250
> EOF
[root#master ~]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
--feature-gates=LocalStorageCapacityIsolation=true \
--kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
--system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
--eviction-hard=memory.available<500Mi,nodefs.available<10% \
--max-pods=250
just use EOF,It can interpret variables, but it can't keep indenting,
[root#master ~]# registry=10.105.100.4/library
[root#master ~]# cat > /etc/sysconfig/kubelet << EOF
> KUBELET_EXTRA_ARGS=--pod-infra-container-image=${registry}/pause:3.1 \
> --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice \
> --feature-gates=LocalStorageCapacityIsolation=true \
> --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi \
> --eviction-hard=memory.available<500Mi,nodefs.available<10% \
> --max-pods=250
> EOF
[root#master ~]# cat /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS=--pod-infra-container-image=10.105.100.4/library/pause:3.1 --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --feature-gates=LocalStorageCapacityIsolation=true --kube-reserved-cgroup=/kubepods.slice --kube-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi --system-reserved-cgroup=/system.slice --system-reserved=cpu=500m,memory=500Mi,ephemeral-storage=1Gi --eviction-hard=memory.available<500Mi,nodefs.available<10% --max-pods=250
[root#master ~]#
Is there any way for both to take effect at the same time?
You have to escape the backslashes at the end of the lines (Tested with bash and zsh; I assume other shells are similar):
$ cat > foo.txt <<EOF
line 1 \\
line 2
EOF
$ cat foo.txt
line 1 \
line 2

Convert parts of strings to another character set

I need to display the text in the utf-8 encoding.
echo "sometext1 ${DATA[1]} \
sometext2 ${DATA[2]} \
sometext3 ${DATA[3]} \
sometext4 ${DATA[4]} \
sometext5 ${DATA[5]}"
sometext* text with the encoding of utf-8
${DATA[1]} Contains digits
${DATA[2]} Contains digits
${DATA[3]} Contains text with the encoding of windows-1251
${DATA[4]} Contains digits
${DATA[5]} Contains text with the encoding of windows-1251
I tried to do the following:
DATA_A=$(${DATA[3]}|iconv -f "windows-1251" -t "UTF-8")
DATA_B=$(${DATA[5]}|iconv -f "windows-1251" -t "UTF-8")
echo "sometext1 ${DATA[1]} \
sometext2 ${DATA[2]} \
sometext3 $DATA_A \
sometext4 ${DATA[4]} \
sometext5 $DATA_B"
And I do not get the conversion of a part of line text.
If i just convert these variables, then everything good:
echo ${DATA[3]}|iconv -f "windows-1251" -t "UTF-8"
echo ${DATA[5]}|iconv -f "windows-1251" -t "UTF-8"
echo was missing in following commands
DATA_A=$(echo "${DATA[3]}"|iconv -f "windows-1251" -t "UTF-8")
DATA_B=$(echo "${DATA[5]}"|iconv -f "windows-1251" -t "UTF-8")
or to avoid a pipe
DATA_A=$(iconv -f "windows-1251" -t "UTF-8" <<< "${DATA[3]}")
DATA_B=$(iconv -f "windows-1251" -t "UTF-8" <<< "${DATA[5]}")

Insert the line with special character (forward slash) in a file in shell script

Script to insert line in file
> cat text
BBLAYERS ?= " \
/home/neeraj/yocto/poky/meta \
/home/neeraj/yocto/poky/meta-yocto \
/home/neeraj/yocto/poky/meta-yocto-bsp \
"
In that I have to insert a line below a pattern as
> cat text
BBLAYERS ?= " \
/home/neeraj/yocto/poky/meta \
/home/neeraj/yocto/poky/meta-yocto \
/home/neeraj/yocto/poky/meta-yocto-bsp \
/home/neeraj/yocto/poky/meta-ti \
"
(Not tested)
Probably what you are looking for:
#!/bin/bash
awk -v search="$1" -v add="$2" '$0 ~ search{$0=$0"\n"add}1' "$3" >$4
exit
Where you would execute with the following format:
user#system:$ ./path-to-script.sh "Line you want to find" "Line you want to add" Input_File Output_File
Let me know if this needs more explanation. :-)

RRDTool GPRINT formatting with printf

Closely related to this question: Bash printf prefix
I have the following Bash script that is generating an RRDGraph with RRDTool.
#!/bin/bash
now=$(date +%s)
now_formatted=$(date +%s | awk '{printf "%s\n", strftime("%c",$1)}' | sed -e 's/:/\\:/g')
# create power graph for last week
/usr/bin/rrdtool graph /var/www/power-week.png \
--start end-7d --width 543 --height 267 --end $now-1min --slope-mode \
--vertical-label "Watts" --lower-limit 0 \
--alt-autoscale-max \
--title "Power: Last week vs. week before" \
--watermark "(©) $(date +%Y) Alyn R. Tiedtke" \
--font WATERMARK:8 \
DEF:Power=/root/currentcost/ccdata.rrd:Power:AVERAGE \
DEF:Power2=/root/currentcost/ccdata.rrd:Power:AVERAGE:end=$now-7d1min:start=end-7d \
VDEF:Last=Power,LAST \
VDEF:First=Power,FIRST \
VDEF:Min=Power,MINIMUM \
VDEF:Peak=Power,MAXIMUM \
VDEF:Average=Power,AVERAGE \
CDEF:kWh=Power,1000,/,168,* \
CDEF:Cost=kWh,.1029,* \
SHIFT:Power2:604800 \
LINE1:Power2#00CF00FF:"Last Week\\n" \
HRULE:Min#58FAF4:"Min " \
GPRINT:Power:MIN:"%6.2lf%sW" \
COMMENT:"\\n" \
LINE1:Power#005199FF:"Power " \
AREA:Power#00519933:"" \
GPRINT:Last:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Average#9595FF:"Average" \
GPRINT:Power:AVERAGE:"%6.2lf%sW" \
COMMENT:"\\n" \
HRULE:Peak#ff0000:"Peak " \
GPRINT:Power:MAX:"%6.2lf%sW" \
COMMENT:"\\n" \
GPRINT:kWh:AVERAGE:" total %6.2lfkWh\\n" \
GPRINT:Cost:AVERAGE:" cost %6.2lf £\\n" \
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
COMMENT:" \\n" \
GPRINT:First:"Showing from %c\\n":strftime \
GPRINT:Last:" to %c\\n":strftime \
COMMENT:" Created at $now_formatted"
Which produces a graph like this (notice the leading \ on the lower cost line in the legend):-
Concentrating specifically on the following line:-
GPRINT:Cost:AVERAGE:"$(printf \\" cost %11s\\" £%.2lf | sed 's/\£/\£ /g')\\n" \
This is the line that is printing out the lower cost line in the legend.
I am passing a GPRINT formatted value of £4.54 to Bash's printf function to be padded out to 11 spaces and a cost label prefixed on it. I am then piping this to sed to add a space between the £ and the actual value.
What I want to know is, why is the escaped \ coming through in the output? If I remove the \\ just after printf bash complains that something is missing.
How would I suppress this \ from coming through in the output.
Try this line:
GPRINT:Cost:AVERAGE:"$(printf ' cost %11s' £%.2lf | sed 's/\£/\£ /g')\\n" \
I changed the inner " marks to ' marks and removed the backslashes.

Unix script Excel report generation

I am creating an Excel file through shell script. The data should be in 4 columns,
but the output data came in one column.
Create a comma-separated values file.
Perhaps, depending on your delimiters:
some process creates colon-separated data | while IFS=: read v1 v2 v3 v4; do
printf "\"%s\",\"%s\",\"%s\",\"%s\"\n" \
"$(sed 's/"/""/g' <<< "$v1")" \
"$(sed 's/"/""/g' <<< "$v2")" \
"$(sed 's/"/""/g' <<< "$v3")" \
"$(sed 's/"/""/g' <<< "$v4")" \
>> my_data.csv
done
Try adding new line at the end of each statement.

Resources