Error in BASH shell script - Using Variables as References - bash

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.

Related

How to grab value back from external script in bash?

I'm sure I'm missing something stupid. I want to pass a full path variable to a perl script, where I do some work on it and then pass it back. So I have:
echo "Backing up: $f ";
$write_file="$(perl /home/spider/web/foo.com/public_html/gen-path.cgi $f)";
echo "WRITE TO: $write_file \n";
However, this gives me:
Backing up: /home/spider/web/foo.com/public_html/websites-uk/uk/q/u
backup-files-all.sh: line 7: =backup-uk-q-u.tar.gz: command not found
WRITE TO: \n
I can't work out why its not saving the output into $write_file. I must be missing something (bash isn't my prefered language, which is why I'm passing to Perl as I'm a lot more fluent in that :))
Unless your variable write_file already exists, the command $write_file="something" will translate to ="something"(1).
When setting a variable, leave off the $ - you only need it if you want the value of the variable.
In other words, what you need is (note no semicolons needed):
write_file="$(perl /home/spider/web/foo.com/public_html/gen-path.cgi $f)"
(1) It can be even hairier if it is set to something. For example, the code:
write_file=xyzzy
$write_file="something"
will result in something being placed into a variable called xyzzy, not write_file :-)

cannot open No such file or directory

I am trying to store the output of total count to a variable and then print the variable.
for i in `cat /home/retailer.sh`;do file = "$(grep $i /home/DD.inventory.loaded_master_list.txt|sort -u|wc -l)";echo $file;done
/home/retailer.sh
HAG
GAT
/home/DD.inventory.loaded_master_list.txt
/dailydata_hershey/prd/work/all/2109/delivery/POSDATA_FINAL.GAT.20200201.dat
/dailydata_hershey/prd/work/all/2109/delivery/POSDATA_FINAL.HAG.20200201.dat
Below error i get
=: cannot open = (No such file or directory)
file = "$(...)" - you have to use file="$(...)" (no spaces).
Otherwise it will be interpreted as a command. (e.g. file with an argument of =)
For future reference, shellcheck.net is a great resource for catching these kinds of things. Just copy-paste your script into the box and it will tell you all of the errors, how to fix them, and a handful of other warnings about potential bugs.

How do I make wildcards work in a bash script

I am trying to run a bash script:
#~/bin/sh
mkdir metaphlan2
echo "Profiling from reads"
echo
samples="CFC280618 MFC280618 SBW280618"
for x in ${samples}
do metaphlan2.py ${x}_S*_R1_001.fastq.gz,${x}_S*_R2_001.fastq.gz --bowtie2out metaphlan2/\${x}.bowtie2.bz2 -o metaphlan2/\${x}.metaphlan2.txt --input_type multifastq --nproc 10
done
Where the * is supposed to represent any character.
However when I ran my script in terminal, I got the following error:
IOError: [Errno 2] No such file or directory: 'SBW280618_S*_R1_001.fastq.gz'
Will anyone be kind enough to help please?
Thank you.
The * is not supposed to represent any character, but to expand the string to match something that exists by substituting the * for whatever is needed.
Unfortunately, you are trying to expand
${x}_S*_R1_001.fastq.gz,${x}_S*_R2_001.fastq.gz
and probably you don't have any file called that way. I'm pretty sure you have two files, one called ${x}_S*_R1_001.fastq.gz and another called ${x}_S*_R2_001.fastq.gz. The comma in the middle make that string to be considered a single string/file.
You need to separate the files between them with spaces. If that's not possible, you will have to expand both files independently and finally generate the string your binary needs.
Try with this second option:
#/bin/sh
mkdir metaphlan2
echo "Profiling from reads"
echo
samples="CFC280618 MFC280618 SBW280618"
for x in ${samples}
do
fq1="${x}"_S*_R1_001.fastq.gz
fq2="${x}"_S*_R2_001.fastq.gz
metaphlan2.py "$fq1,$fq2" --bowtie2out metaphlan2/\${x}.bowtie2.bz2 -o metaphlan2/\${x}.metaphlan2.txt --input_type multifastq --nproc 10
done

parameter expansion syntax bash

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

Why doesn't this bit of code work? Setting variables and config file

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.

Resources