You are not logged in.
Ok, in principal, I need to have bash read in a file and make substitutions for variables I have defined in a skeleton file. Kind of like a form letter. Why? I have torque installed on my machine and I need to have my repo-ck build script make a custom build.sh that each respective cluster job will call.
I'm no student and this isn't homework. Anyway, here is an oversimplified example
letter.skl:
Dear $name,
The party starts at $time.
Regards,
$me
So the bash script defines all three of those variables and needs to read in the letter.skl and pipe it into a new file that contains the "final" output. How can this be accomplished?
#!/bin/bash
name="John"
time="11 o'clock"
me="graysky"
...
Last edited by graysky (2011-06-18 22:38:33)
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
I would do it sort of the other way round:
[karol@black ~]$ cat tg
#!/bin/bash
. variables
echo "Dear $name,
The party starts at $time.
Regards,
$me"
[karol@black ~]$ cat variables
name="John"
time="11 o'clock"
me="graysky"
[karol@black ~]$ ./tg
Dear John,
The party starts at 11 o'clock.
Regards,
graysky
Offline
Define the inputs in separate files, perhaps, and iterate over them using a heredoc to print the output. The subshell keep the environment clean (though every var should be defined, or you should be checking for this...)
#!/bin/bash
formletter() {
cat<<EOF
Dear $recipient,
I regret to inform you that at $time on $date, I accidentally ran over your pet $animal.
Please be assured that they died painlessly as my hot pink 1986 camaro crushed their
$bodypart within a fraction of a second. While I would like to offer some amount of money
as reparations, it seems that I do not get paid very well as a $occupation, and am unable
to provide anything more than a shoulder to cry on.
Regards,
$randomname
EOF
}
for input in /path/to/inputs/*; do
(
. "$input"
formletter > /path/to/output/"output-${input##*/}"
)
done
Offline
Yeah... this is how I'm doing it now, but it's very clunky. I need to generate within my build.functions two files:
1) A build script unique to each arch and cpu package
2) A queue file for the cluster that will call #1
I have leveraged the echo method as I said, but its not elegant and very ugly. What would be far better would be for me to have a skeleton script I can read in, substitute and write out if this is possible natively in bash.
Example of my "ugly" code:
# make cluster.pbs
echo "#!/bin/bash" > $pkgarch-$arch.pbs
echo "#PBS -l nodes=1,walltime=1:00:00" >> $pkgarch-$arch.pbs
echo "#PBS -N $arch-$pkgarch" >> $pkgarch-$arch.pbs
echo " " >> $pkgarch-$arch.pbs
echo "[[ $arch = \"x86_64\" ]] && $workdir/build-$pkgarch-$arch.sh" >> $pkgarch-$arch.pbs
echo "[[ $arch = \"i686\" ]] && sudo linux32 chroot /opt/arch32 /bin/bash -c $workdir/build-$pkgarch-$arch.sh ; sleep 1s" >> $pkgarch-$arch.pbs
# make script it needs if building in chroot
echo "#!/bin/bash" > $workdir/build-$pkgarch-$arch.sh
echo ". /home/$me/.credentials" >> $workdir/build-$pkgarch-$arch.sh
echo "cd $workdir" >> $workdir/build-$pkgarch-$arch.sh
echo "whatarch=\$(uname -m)" >> $workdir/build-$pkgarch-$arch.sh
echo "if [ \$whatarch = \"x86_64\" ]; then" >> $workdir/build-$pkgarch-$arch.sh
echo " makepkg -g >> PKGBUILD && makepkg -sc" >> $workdir/build-$pkgarch-$arch.sh
echo "else" >> $workdir/build-$pkgarch-$arch.sh
echo "su -c \"makepkg -g >> PKGBUILD && makepkg -sc\" $me" >> $workdir/build-$pkgarch-$arch.sh
echo "fi" >> $workdir/build-$pkgarch-$arch.sh
echo " " >> $workdir/build-$pkgarch-$arch.sh
echo "for i in PKGBUILD \"\$_config\"; do" >> $workdir/build-$pkgarch-$arch.sh
echo "mv \$i $des_cluster/repo/$arch/files/\$i.$pkgarch" >> $workdir/build-$pkgarch-$arch.sh
echo "done" >> $workdir/build-$pkgarch-$arch.sh
echo " " >> $workdir/build-$pkgarch-$arch.sh
echo "x=0" >> $workdir/build-$pkgarch-$arch.sh
echo "for i in \$(ls *.xz); do" >> $workdir/build-$pkgarch-$arch.sh
echo " array[\$x]=\$i" >> $workdir/build-$pkgarch-$arch.sh
echo " x=\$(( \$x +1 ))" >> $workdir/build-$pkgarch-$arch.sh
echo " mv \$i $des_cluster/repo/$arch" >> $workdir/build-$pkgarch-$arch.sh
echo "done" >> $workdir/build-$pkgarch-$arch.sh
echo " " >> $workdir/build-$pkgarch-$arch.sh
echo "files=\$(echo \${array[@]}|sed s'/\ /,/')" >> $workdir/build-$pkgarch-$arch.sh
echo "if [ \$whatarch = \"x86_64\" ]; then" >> $workdir/build-$pkgarch-$arch.sh
echo " curl -u \$myusername:\$mypasswd -T $des_cluster/repo/$arch/{\$files} ftp://\$mysite/\$arch/ -s &" >> $workdir/build-$pkgarch-$arch.sh
echo "else" >> $workdir/build-$pkgarch-$arch.sh
echo " su -c \"curl -u \$myusername:\$mypasswd -T $des_cluster/repo/$arch/{\$files} ftp://\$mysite/\$arch/ -s & $me" >> $workdir/build-$pkgarch-$arch.sh
echo "fi" >> $workdir/build-$pkgarch-$arch.sh
chmod +x $workdir/build-$pkgarch-$arch.sh
qsub $pkgarch-$arch.pbs > /dev/null
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
To answer the OP :
#!/bin/bash
name="John"
time="11 o'clock"
me="graysky"
>letter.txt
while read line; do
eval echo "$line" >>letter.txt
done <letter.skl
Offline
@baerbae - nice thanks!
How can I "protect" some variables in letter.txt using this method?
Example:
letter.skl:
$name
$who
$time
\$name
After running the code, all variables get replaces included the \$name.
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
use two backslashes in letter.skl :
\\$name
Offline
@berbae - this is killer! Thank you!
@falconindy - thank you for your post which I didn't see until now. I like it!
Last edited by graysky (2011-06-18 22:41:55)
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline
Variation on the theme with this. See this commit in my github and thank you for the suggestions -- this is much more elegant than what I initially had!
Last edited by graysky (2011-06-19 10:22:42)
CPU-optimized Linux-ck packages @ Repo-ck • AUR packages • Zsh and other configs
Offline