How does awk distinguish between arguments and input file? - awk

This is my shell script that receives a string as an input from the user from the stdin.
#!bin/sh
printf "Enter your query\n"
read query
cmd=`echo $query | cut -f 1 -d " "`
input_file=`echo $query | cut -f 2 -d " "`
printf $input_file
if [ $input_file = "" ]
then
printf "No input file specified\n"
exit
fi
if [ $cmd = "summary" ]
then
awk -f summary.awk $input_file $query
fi
Lets say he enters
summary a.txt /o foo.txt
Now cmd variable will take the value summary and input_file will take a.txt.
Isn't that right?
I want summary.awk to work on $input_file, based on what is present in $query.
My understanding is as follows :
The 1st command line argument passed is treated as input file.
e.g. : awk 'code' file arg1 arg2 arg3
only file is treated as input file
If the input file is piped, it doesn't see any of the arguments as input files.
e.g. : cat file | awk 'code' arg1 arg2 arg3
arg1 is NOT treated as input file.
Am I right?
The problem is
I get awk: cannot open summary (No such file or directory)
Why is it trying to open summary?
It is the next word after $input_file.
How do I fix this issue?

If there's no -f option, the first non-option argument is treated as the script, and the remaining arguments are input files. If there's a -f option, the script comes from that file, and the rest are input files.
If and only if there are no input file arguments, it reads the input from stdin. This means if you pipe to awk and also give it filename arguments, it will ignore the pipe.
This is the same as most Unix file-processing commands.
Try this:
awk -f summary.awk -v query="$query" "$input_file"
This will set the awk variable query to the contents of query.

Related

How to make sed command handle the escape characters in the input parameters that are not user-typed?

I've a file inside which I have a placeholder text for a password. I'm now trying to find and replace the placeholder text with the actual password. The text looks like below:
USER_GIVEN_PASSWORD=<my_password>
Let's say my password is: ABC&12345
I'm using the below command inside a script to replace this:
sed -i "s/<my_password>/$1/g" file.txt
I pass the input to my script as below:
sh password_replace.sh ABC&12345
My expected output is:
USER_GIVEN_PASSWORD=ABC&12345
But I'm getting the below output:
USER_GIVEN_PASSWORD=ABC<my_password>12345
Clearly, I'm doing something wrong with the & symbol present in my password. So, when I tried with escaping & in my input as follows, it actually works:
sh password_replace.sh ABC'\&'12345
But the problem is I should not adjust the input parameter to pass an escape character because the password won't be manually typed. It will automatically come from something like the Azure key vault as the input to my script.
So, I need to make the sed command itself handle the incoming special characters.
Can someone please help me achieve this?
Sed doesn't understand literal strings, just regexps and backreference-enabled replacement text. See Is it possible to escape regex metacharacters reliably with sed for the lengths you have to go to to try to get sed to behave as if you were using literal strings.
Just use the literal string functions in awk instead:
$ new='ABC&12\345' awk '
BEGIN { old="<my_password>"; lgth=length(old); new=ENVIRON["new"] }
s = index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+lgth) }
1' file
USER_GIVEN_PASSWORD=ABC&12\345
That will work for any character, no need to do any escaping.
In your shell script where you're trying replace with $1 you'd just do:
new="$1" awk 'script' file
If you're using GNU awk you can use -i inplace just like you can use -i with GNU sed:
new="$1" awk -i inplace 'script' file
or with any awk:
tmp=$(mktemp)
new="$1" awk 'script' file > "$tmp" && mv "$tmp" file
It's important for new=... to be at the start of the same line as the awk command starts on so ENVIRON[] can access it without it having to be exported.
As others have commented, & is a reserved word in sed and will need to be "escaped" in order to be used in substitute text. An alternative approach would be to use awk (GNU awk in this case):
awk -v pass="$pass" -v confpass="$confpass" -v schepass1="$schepass1" -v schepass2="$schpass2" '/USER_GIVEN_PASS/ { match($0,"<my_password>");$0=substr($0,1,RSTART-1)pass""substr($0,RSTART+RLENGTH) } /CONFIRM_USER_GIVEN_PASSWORD/ { match($0,"<my_password>");$0=substr($0,1,RSTART-1)confpass""substr($0,RSTART+RLENGTH) } /SCHEMA1_PASSWORD/ { match($0,"<db_password>");$0=substr($0,1,RSTART-1)schpass1""substr($0,RSTART+RLENGTH) } /SCHEMA2_PASSWORD/ { match($0,"<db_password>");$0=substr($0,1,RSTART-1)schpass2""substr($0,RSTART+RLENGTH) }1' file
Pass the password to awk as a variable "pass". When the line containing "USER_GIVEN_PASS" is encountered, match the position of the "holder" using awk's match function. Set the line ($0) equal to the string up to the place holder, pass, then the rest of the string.
If you have later versions of GNU awk, you can use -i to commit the changes back to the file once you are happy.
Otherwise:
awk -v pass="$pass" '/USER_GIVEN_PASS/ { match($0,"<my_password>");$0=substr($0,1,RSTART-1)pass""substr($0,RSTART+RLENGTH) }1' file > tmpfile && mv -f tmpfile file

Extracting data after a tag and CR with Busybox sed

I have a script that extracts a file from a bash script combined with a binary file. It does so using the following GNU sed syntax
sed -n '/__DATA__/{n;:1;n;p;b1}' /tmp/combined.file > /tmp/binary.file
The files are assembled by cat'ing an ISO file to the end of a bash script. Which is then sent over the network to an embedded device and extracted on the device, piping the ISO file to a temporary dir and executing the bash script to install it.
However, on executing this I get a
sed: unterminated {
Am I missing something here? Is this task possible with BusyBox sed?
It tried the "Second attempt" below with OSX/BSD awk and it failed, just printing up til the first NUL character. So you can't do this job portably with awk or sed.
Here's what should work everywhere given that the POSIX standard says
the input file to tail can be any type
so the input to tail doesn't have to be a POSIX text file (no NULs) and we're exiting from awk before the first NUL is encountered in the input so they should both be happy:
$ tail -n +"$(awk '/^__DATA__$/{print NR+2; exit}' binary.bin)" binary.bin | cat -ev
ER^H^#^#^#M-^PM-^P^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#3��M-^Nռ^#|��f1�f1�fSfQ^FWM-^N�M-^N�R�^#|�^#^F�^#^A��K^F^#^#R�A��U1�0���^Sr^VM-^A�U�u^PM-^C�^At^Kf�^F�^F�B�^U�^B1�ZQ�^H�^S[^O��#PM-^C�?Q��SRP�^#|�^D^#f��^G�D^#^OM-^BM-^#^#f#M-^#�^B��fM-^A>#|��xpu ��{�D|^#^#�M-^C^#isolinux.bin missing or corrupt.^M$
f`f1�f^C^F�{f^S^V�{fRfP^FSj^Aj^PM-^I�f�6�{��^FM-^H�M-^H�M-^R�6�{M-^H�^H�A�^A^BM-^J^V�{�^SM-^Md^Pfa��^^^#Operating system load error.^M$
^��^NM-^J>b^D�^G�^P<$
u��^X���^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#L^D^#^#^#^#^#^#�K�6^#^#M-^#^#^A^#^#?�M-^K^#^#^#^#^#`^\^#^#�������<R^#^#^#^_^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#U�EFI PART^#^#^A^#\^#^#^#]3�.^#^#^#^#^A^#^#^#^#^#^#^#�_^\^#^#^#^#^##^#^#^#^#^#^#^#�_^\^#^#^#^#^#Uc�r^Oqc#M-^Rc^F�$LZ�^L^#^#^#^#^#^#^#�^#^#^#M-^#^#^#^#�t^]F^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#$
Second attempt:
Now that I have a better idea what you're trying to do (process a file consisting of POSIX text lines up to a point and then can contain NUL characters afterwards), try this:
$ cat -ev file
echo "I: Installation finished!"$
exit 0$
$
__DATA__$
$
foo^#bar^#etc
$ cat tst.awk
/^__DATA__$/ { n=NR + 1 }
n && (NR == n) { RS="\0"; ORS="" }
n && (NR > n) { print (c++ ? RS : "") $0 }
$ awk -f tst.awk file | cat -ev
foo^#bar^#etc
The above doesn't try to store any input lines containing NUL in memory, instead it reads \n-terminated text lines until it reaches the line after the one containing __DATA__ and then switches to reading NUL-terminated records into memory and printing NULs between them on output.
It's still undefined behavior per POSIX (see my comments below) but in theory it should work since it just relies on being able to set one variable (RS) to NUL rather than trying to store input strings that contain NULs. Also, setting RS to NUL has been a (flawed) workaround for awk scripts for years to be able to read a whole file into memory at once so being able to set RS to NUL should work in any modern awk.
Using the new sample you provided with the missing blank line after the __DATA__ line added:
$ cat -ev file
#!/bin/bash$
$
echo "I: Awesome Things happened here"$
exit 0$
$
__DATA__$
$
ER^H^#^#^#M-^PM-^P^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#3M-mM-zM-^NM-UM-<^#|M-{M-|f1M-[f1M-IfSfQ^FWM-^NM-]M-^NM-ERM->^#|M-?^#^FM-9^#^AM-sM-%M-jK^F^#^#RM-4AM-;M-*U1M-I0M-vM-yM-M^Sr^VM-^AM-{UM-*u^PM-^CM-a^At^KfM-G^FM-s^FM-4BM-k^UM-k^B1M-IZQM-4^HM-M^S[^OM-6M-F#PM-^CM-a?QM-wM-aSRPM-;^#|M-9^D^#fM-!M-0^GM-hD^#^OM-^BM-^#^#f#M-^#M-G^BM-bM-rfM-^A>#|M-{M-#xpu M-zM-<M-l{M-jD|^#^#M-hM-^C^#isolinux.bin missing or corrupt.^M$
f`f1M-Rf^C^FM-x{f^S^VM-|{fRfP^FSj^Aj^PM-^IM-ffM-w6M-h{M-#M-d^FM-^HM-aM-^HM-EM-^RM-v6M-n{M-^HM-F^HM-aAM-8^A^BM-^J^VM-r{M-M^SM-^Md^PfaM-CM-h^^^#Operating system load error.^M$
^M-,M-4^NM-^J>b^DM-3^GM-M^P<$
uM-qM-M^XM-tM-kM-}^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#L^D^#^#^#^#^#^#M-/KM-66^#^#M-^#^#^A^#^#?M-`M-^K^#^#^#^#^#`^\^#^#M-~M-^?M-^?M-oM-~M-^?M-^?<R^#^#^#^_^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#UM-*EFI PART^#^#^A^#\^#^#^#]3M-%.^#^#^#^#^A^#^#^#^#^#^#^#M-^?_^\^#^#^#^#^##^#^#^#^#^#^#^#M-J_^\^#^#^#^#^#UcM-)r^Oqc#M-^Rc^FM-2$LZM-p^L^#^#^#^#^#^#^#M-P^#^#^#M-^#^#^#^#M-{t^]F^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#$
.
$ awk -f tst.awk file | cat -ev
ER^H^#^#^#M-^PM-^P^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#3M-mM-zM-^NM-UM-<^#|M-{M-|f1M-[f1M-IfSfQ^FWM-^NM-]M-^NM-ERM->^#|M-?^#^FM-9^#^AM-sM-%M-jK^F^#^#RM-4AM-;M-*U1M-I0M-vM-yM-M^Sr^VM-^AM-{UM-*u^PM-^CM-a^At^KfM-G^FM-s^FM-4BM-k^UM-k^B1M-IZQM-4^HM-M^S[^OM-6M-F#PM-^CM-a?QM-wM-aSRPM-;^#|M-9^D^#fM-!M-0^GM-hD^#^OM-^BM-^#^#f#M-^#M-G^BM-bM-rfM-^A>#|M-{M-#xpu M-zM-<M-l{M-jD|^#^#M-hM-^C^#isolinux.bin missing or corrupt.^M$
f`f1M-Rf^C^FM-x{f^S^VM-|{fRfP^FSj^Aj^PM-^IM-ffM-w6M-h{M-#M-d^FM-^HM-aM-^HM-EM-^RM-v6M-n{M-^HM-F^HM-aAM-8^A^BM-^J^VM-r{M-M^SM-^Md^PfaM-CM-h^^^#Operating system load error.^M$
^M-,M-4^NM-^J>b^DM-3^GM-M^P<$
uM-qM-M^XM-tM-kM-}^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#L^D^#^#^#^#^#^#M-/KM-66^#^#M-^#^#^A^#^#?M-`M-^K^#^#^#^#^#`^\^#^#M-~M-^?M-^?M-oM-~M-^?M-^?<R^#^#^#^_^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#UM-*EFI PART^#^#^A^#\^#^#^#]3M-%.^#^#^#^#^A^#^#^#^#^#^#^#M-^?_^\^#^#^#^#^##^#^#^#^#^#^#^#M-J_^\^#^#^#^#^#UcM-)r^Oqc#M-^Rc^FM-2$LZM-p^L^#^#^#^#^#^#^#M-P^#^#^#M-^#^#^#^#M-{t^]F^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#$
Original answer:
Assuming this question is related to your previous question, this will work using any awk in any shell on every UNIX box:
$ awk '/^__DATA__$/{n=NR+1} n && NR>n' file
3<ED>M-^PM-^PM-^PM-^PM-^
When it finds __DATA__ it sets a variable n to the line number to start printing after and then when n is set prints every line for which the line number is greater than n.
The above was run against this input file from your previous question:
$ cat -ev file
echo "I: Installation finished!"$
exit 0$
$
__DATA__$
$
3<ED>M-^PM-^PM-^PM-^PM-^$

How can I arrange the input filename and additional arguments when writing an awk script?

I would like to write an awk script, so that
I can run the script name directly in bash without writing awk as the command name.
How can I arrange the input filename and additional arguments to be specified at command line and passed into the script?
Should the script, say myscript.awk start with a shebang:
#! /usr/bin/awk -f
or
#! /usr/bin/awk
or no shebang?
How I shall I write the script to handle the command line arguments, so that I can run it like myscript.awk inputfile arg1 arg2 or myscript.awk arg1 arg2 inputfile ?
How should I handle the options to awk, such as -F'\t'?
Or what are some alternative ways to do it?
Or shall I do it indirectly, by writing a bash script which calls awk on my awk program?
Thanks
I prefer to use bash to do most of the job, and then invoke awk with all the parameters. That way you have full access to bash builtins and other things.
You can do something like this:
#!/bin/bash
var1=$1
var2=$2
separator=$3
awk -F "$separator" -v myvar1="$var1" -v myvar2="$var2" '
BEGIN {
print myvar1, myvar2
}
'
Double quotes are good in case your parameters contain spaces (like many filenames).

Sed / Awk : replace the first occurrence of a pattern with the content of another file

With sed, I'm trying to replace the first occurrence of a comment in a script, like :
#ENTRYPOINT_CONTENT
by the content of a second file ($file_content) into another third file (/base.sh).
So, according to many docs, the string should be quite simple, something like :
sed "s|\#ENTRYPOINT_CONTENT|$file_content|" /base.sh
But I always end up with errors like :
sed: -e expression #1, char 23: unterminated s' command
or similar messages, also tried different delimiters, even with Awk instead, but without success, it seems to be fine after escaping the # in the search pattern, but I still can't get the file content as a variable in Sed.
Any ideas, either with Sed or Awk ?
Edit : --------------------
#Sundeep #James Brown:
Don't want to mix the subjects nor to be long :) the response to you clarification request is in bold at the end of this edit, but just to elaborate the context, my case is a Docker entrypoint script in bash (for a base Docker image) called /root/test/base :
#!/usr/bin/env bash
#ENTRYPOINT_CONTENT
if [[ -e "/root/test/custom" ]]; then
printf "\n\n#ENTRYPOINT_CONTENT\n" >> /root/test/custom
# Code from whjm's reply below (actually works but appends shebangs from custom files)
sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh
mv /root/test/base2.sh /root/test/base.sh
rm -f /root/test/custom
fi
I just want to let users drop another bash script of their own on a specific path (say /root/test/custom), for example :
#!/usr/bin/env bash
echo 'My 2nd bash code'
The first script above (base) should insert the content of the custom file at #ENTRYPOINT_CONTENT position (in the base script itself, without removing this search string), like this :
#!/usr/bin/env bash
echo 'My 2nd bash code'
#ENTRYPOINT_CONTENT
if [[ -e "/root/test/custom" ]]; then
printf "\n\n#ENTRYPOINT_CONTENT\n" >> /root/test/custom
# Code from whjm's reply below
sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh
mv /root/test/base2.sh /root/test/base.sh
rm -f /root/test/custom
fi
If another user later drops another custom script at the same path, we should have the code of this third custom script appended like this :
#!/usr/bin/env bash
echo 'My 2nd bash code'
echo 'My 3rd bash code'
#ENTRYPOINT_CONTENT
if [[ -e "/root/test/custom" ]]; then
# ... and so on
Regarding the shebangs from custom files, it's not a real issue if they are appended to the base file, the sed code from #whjm works as expected but appends them, while (surprisingly) both awk codes from #James Brown already (and gracefully :) ignore all additional shebangs from custom files (probably because they also start with # as the #ENTRYPOINT_CONTENT search string) but currently partly preprend the code like :
#!/usr/bin/env bash
echo 'My 3rd bash code'
echo 'My 2nd bash code'
#ENTRYPOINT_CONTENT
while I'm trying to get it appended like :
#!/usr/bin/env bash
echo 'My 2nd bash code'
echo 'My 3rd bash code'
#ENTRYPOINT_CONTENT
So, in short, #Sundeep, if you could just give me an updated version of your awk code for this, it would be perfect ! :D (couldn't find a way to invert this...) Thanks a lot.
Code from your previous post :
NR==FNR { b=b (FNR==1?"":ORS) $0; next }
{ r=r (FNR==1?"":ORS) $0 } #ENTRYPOINT_CONTENT
END { sub(/\#[^\n]+/,r,b); print b}
If you're using GNU sed:
[STEP 101] # cat file1
11
xx // replace me
44
xx // don't replace me
55
[STEP 102] # cat file2
22
33
[STEP 103] # sed -e '0,/^xx/!b; /^xx/{ r file2' -e 'd }' file1
11
22
33
44
xx // don't replace me
55
[STEP 104] #

Script to copy one column data to another column

I am writing a script to copy one column data to another column.
Tried with following logic bud didnt worked out-
o/p- number of parameter is 0.
My Logic-
• I got the keys from the admintable and then copied the data to some updateupdateStatement file.
• Using awk command I copied specific column data to some temp file
• Then prepared an update statement and then executed it.
#!/bin/ksh
#
# Script to Populate cross_refs based on what is in cross_references
#
#
echo "number of parameters is $#"
if [ $# != 1 ]; then
USAGE="USAGE: $0 cassPassword"
echo ${USAGE}
exit 1
fi
cassPassword=$1
#Add column to admin table
#echo "alter table to add column..."
#echo "ALTER TABLE admin.product ADD cross_refs Map<String,String>;" > updateTable.cql
#cqlsh -u dgadmin -p ${cassPassword} -f updateTable.cql
echo "get keys from cassandra"
echo "copy admin.product (cross_references) to 'updateupdateProductStatement.cql';" > copyInputs.cql
cqlsh -u dgadmin -p ${cassPassword} -f copyInputs.cql
#Convert file that Cassandra created from DOS to Unix
echo "DOS to Unix conversion..."
tr -d '\015' <updateupdateProductStatement.cql >updateupdateProductStatement2.cql
cat updateupdateProductStatement2.cql >tempFile
sed -i "s/^/update admin.product set cross_refs = '/" tempFile
#execute the updated .cql file to run all the update statements
echo "executing updateupdateProductStatement.cql..."
cqlsh -u dgadmin -p ${cassPassword} -f tempFile
I'm not absolutely certain I understand the intent of your script, but I can pick out one line that looks suspect...
cat updateFlatFileInputStatements2.cql |awk -F'\t' '{ 19 1 2}' >tempFile
I think you want to print columns 19, 1 and 2 to your output...
awk -F'\t' 'BEGIN { OFS=" " }{ print $19, $1, $2 }' updateFlatFileInputStatements2.cql > tempFile
Better is to do all the manipulation of tempFile in awk
awk -F'\t' "{ print \"update admin.product set my_refs = \" \$19 \" where id = \" $1 \" and effective_date = \" $2 \"';\"" updateFlatFileInputStatements2.cql > tempFile
Then again, I don't see in your file where tempFile is used... or where updateFlatFileInputStatements2.cql is generated. Looks like this piece of code is doing nothing?
updateupdateStatement.cql ... don't know where that comes from. This then is stripped to form updateupdateStatement2.cql ... which then is manipulated to become tempFile but... you don't use tempFile -- instead you send updateupdateStatement2.cql to cqlsh. The bug may be that you intended to send tempFile instead to your final cqlsh.