I have little scripting experience. I have tried a new script to loop through multiple subdirectories and edit a file if the subdirectory exists. Here is the code I've failed with after multiple attempts, but I cannot resolve the for loop error:
!#/usr/din/sh
for domain in {PGBWAHS_NA PGBWAHS04_NA PGBWAHD_NA PGBWAHD04_NA PGBWAHQ_NA PGBWAHQ02_NA PGBWAHQ03_NA PGBWAHQ04_NA PGBWAHP_NA PGBWAHP02_NA PGBWAHP03_NA PGBWAHP04_NA
do
echo "$domain this is the current domain from the array"
cd /opt/tibco/tra/domain/$domain
echo `pwd` "this is the directory after cd command"
cp hawkagent.cfg hawkagent.cfg.back
sed 's/-scan_rate 10/-scan_rate 30/' hawkagent.cfg
Done
____________________
Error message returned:
$ ./modify_log_scan_rate.sh
./modify_log_scan_rate.sh[3]: Syntax error at line 3 : `for' is not matched.
Remove the opening curly braces after in: for domain in *{*PGBWAHS_NA ...
Done needs to be done (case matters).
– Etan Reisner
Related
I am trying to create directories whose names are variables defined in an array. When I run my code below I do not understand the errors
#!/bin/bash
#
Output_Base_Dirs=(/home/user/CORDEX/OUTPUT/historical /home/user/CORDEX/OUTPUT/rcp45)
Input_Base_Dirs=(/home/user/CORDEX/INPUT/historical /home/user/CORDEX/INPUT/rcp45)
Input_Data_Dirs=(CLMcom-CCLM4-8-17_v1/CNRM-CERFACS-CNRM-CM5_r1i1p1/day/native)
Var_Dirs=(precip tmin tmax)
Vars=(pr tasmin tasmax)
# Create directories called by the variable name, if not there
###########################################################
for i in "${Output_Base_Dirs[#]}"
do
echo $Var_Dirs[i]
# if [ ! -d ${Var_Dirs[i]} ]; then
echo $Var_Dirs[i]
echo "Directory doesn't exist. Creating now"
mkdir "$Output_Base_Dirs[i]/$Var_Dirs[i]"
echo "File created"
# else
# echo "Directory exists"
# fi
done
exit 0
When I run the above code with the if construct in place I get an error at the line of the if, as follows
precip[i]
./merge_files.sh: line 55: /home/user/CORDEX/OUTPUT/historical: syntax error: operand expected (error token is "/home/user/CORDEX/OUTPUT/historical")
When I run the code with the if construct commented out, I get the following
precip[i]
Directory doesn't exist. Creating now
mkdir: cannot create directory ‘/home/user/CORDEX/OUTPUT/historical[i]/precip[i]’: No such file or directory
File created
precip[i]
Directory doesn't exist. Creating now
mkdir: cannot create directory ‘/home/user/CORDEX/OUTPUT/historical[i]/precip[i]’: No such file or directory
File created
Why does
echo $Var_Dirs[i]
print "precip[i]"?
I will appreciate to understand what is the problem and how to do it properly.
Quoting from Bash Reference Manual § 6.7 Arrays;
Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with pathname expansion.
...
Referencing an array variable without a subscript is equivalent to referencing the array with a subscript of 0.
That means,
$Var_Dirs[i]
is the same as
${Var_Dirs[0]}[i]
, thus history[i], precip[i], etc. in the output.
The correct syntax is:
${Var_Dirs[i]}
But,
fixing it won't make your script work. Because "${Output_Base_Dirs[#]}" expands to the values in array Output_Base_Dirs, and you're using them as indexes.
I am trying to write a short script that will take two command line parameters as file extensions and change all files with the first extension to have the second extension. I am pretty sure the following script should work but for some reason it gives me a syntax error on the line where the variable name is defined and I am not sure why. I am rather new to bash scripting so any help would be greatly appreciated!
for f in "*$1" do
name=${f%.*}
mv $f "$name$2"
done
The error message printed by Bash looks like:
./script: line 4: syntax error near unexpected token `name=${f%.*}'
./script: line 4: `name=${f%.*}'
The reason is that you are missing a ; or newline before do. Also you don't want to quote * in "*$1", since the * will be taken as a literal. Corrected script:
#!/usr/bin/env bash
for f in *"$1"; do
name=${f%.*}
mv "$f" "$name$2"
done
Two questions about problems I'm having writing up a BASH script that uses variables. I cannot for the life of me figure this out and it is KILLING me.
1) I have the following code.
pdir=/media/The_Enforcer/ICA_Doug/Participants/RS1
cd ${pdir}
for subject in * ; do
subdir=${pdir}/${subject} ;
cd ${subdir} ;
subj= echo ${subject} | head -c-9
3dAFNItoNIFTI -prefix ICA/cleanRS_NII_${subj} RSFC_LFF_rall_${subj}+orig ;
cd ${pdir} ;
done
${subject} is a subject ID which is ########.results. For example: 1R101U1A.results. Basically my code cd's me into that directory in which is a file called RSFC_LFF_rall_1R101U1A+orig which I want to process via the code line that starts with 3dAFNItoNIFTI. Obviously I can't use ${subject} variable in that code line because it would attempt to find the file RSFC_LFF_rall_1R101U1A.results+orig which does not exist. So to fix this I made a new variable called ${subj} which, via the echo pipeline, basically cuts off the last 9 letters of ${subject} which, in effect, removes the .results. When I do this and echo ${subj} it gives me 1R101U1A which is exactly what I want.
However, the line of code that starts with 3dAFNItoNIFTI errors with the following:
FATAL ERROR: Can't open dataset 'RSFC_LFF_rall_+orig'
I have tried declaring the ${subj} variable like, five different ways (including using head, tail, cut, and colons) and I still get this error.
What am I doing wrong?
2) In attempting to define ${subj} in numerous ways I also tried this method:
${subj}= ${subject:0:8}
When I did this, the final bracket refused to close - i.e. the closing bracket did not turn the color of the opening bracket and when I attempted to run the script I got an error at that line saying 'command not found.' I checked my syntax against the examples I was following and it looks fine? Am I missing something here?
Try this:
cd "/media/The_Enforcer/ICA_Doug/Participants/RS1"
for subject in * ; do
cd $subject
subj=${subject%.results}
3dAFNItoNIFTI -prefix ICA/cleanRS_NII_${subj} RSFC_LFF_rall_${subj}+orig
cd ..
done
${subject%.results} removes .results from the end of the string.
See Shell-Parameter-Expansion.
I have recently just made this script:
if test -s $HOME/koolaid.txt ; then
Billz=$(grep / $HOME/koolaid.txt)
echo $Billz
else
Billz=$HOME/notkoolaid
echo $Billz
fi
if test -d $Billz ; then
echo "Ok"
else touch $Billz
fi
So basically, if the file $HOME/koolaid.txt file does NOT exist, then Billz will be set as $HOME/koolaid.txt. It then sucesfully creates the file.
However, if I do make the koolaid.txt then I get this
mkdir: cannot create directory : No such file or directory
Any help would be appreciated
Here is a difference between content of a variable and evaluated content...
if your variable contains a string $HOME/some - you need expand it to get /home/login/same
One dangerous method is eval.
bin=$(grep / ~/.rm.cfg)
eval rbin=${bin:-$HOME/deleted}
echo "==$rbin=="
Don't eval unless you're absolutely sure what you evaling...
Here are a couple things to fix:
Start your script with a "shebang," such as:
#!/bin/sh
This way the shell will know that you want to run this as a Bourne shell script.
Also, your conditional at the top of the script doesn't handle the case well in which .rm.cfg exists but doesn't contain a slash character anywhere in it. In that case the rbin variable never gets set.
Finally, try adding the line
ls ~
at the top so you can see how the shell is interpreting the tilde character; that might be the problem.
I'm making a makefile and I'm working on a target with no dependencies that checks to see if a file named README exists in the current directory and if it does, read it using less or else exit quitely: give no errors whatsoever--the command to run the target should print nothing to console if this is the case.
I've tried a couple different ways but nothing really seems to work (PAGER is simply a var equal to less):
read :
ifneq ("$(wildcard README)","")
-#$(PAGER) README
endif
And also with this code
read :
-#for file in *;\
do \
if [ ${file} == "README" ]; then\
$(PAGER) "README" ;\
fi;\
done
With the first chunk I keep getting an error akin to /bin/sh: Syntax error: word unexpected (expecting ")") and for the life of me I just don't get what it's saying. I certainly don't think there's a syntax error, perhaps I'm misusing make.
For the latter code I get an unexpected operator error for the ==.
I've also tried simpler things like these two single liner solutions but get similar errors:
-#test -a README && less README
-#[ -a README ] && less README
Any help would be greatly appreciated.
EDIT: I was digging further and saw something promising and explicitly setting my shell to /bin/bash (SHELL := /bin/bash) yet no dice.
read:
#if [ -e README ]; then less README; fi
You should try to extract your shell code in separate *.sh files so that you can specify them as commands in your makefile (and make sure that the *.sh files are executable).