1

Error is listed below:

merge_star.sh: line 19: syntax error near unexpected token `('
merge_star.sh: line 19: `cat <(cat ~/asn_project/alignment_sorted/tmp/header.txt | sed 's/ /\t/g') ~/asn_project/alignment_sorted/tmp/tmp.out > ~/asn_project/alignment_sorted/STAR_counts.txt'

Line in .sh script in question:

cat <(cat ~/asn_project/alignment_sorted/tmp/header.txt | sed 's/ /\t/g') ~/asn_project/alignment_sorted/tmp/tmp.out > ~/asn_project/alignment_sorted/STAR_counts.txt
#!/bin/bash
# create header file
echo gene_name $(cd ~/asn_project/alignment_sorted && ls *_ReadsPerGene.out.tab | sed s/_ReadsPerGene.out.tab// | sort -u) > ~/asn_project/alignment_sorted/tmp/header.txt

# Place each sample's STAR gene count file - ReadsPerGene.out.tab in the tmp/ directory 
# The 2nd column (-f2) of ReadsPerGene.out.tab contains the non-stranded counts
for sample in $(cd ~/asn_project/alignment_sorted && ls *_ReadsPerGene.out.tab | sed s/_ReadsPerGene.out.tab// | sort -u)
do 
    echo ${sample}
    cat ~/asn_project/alignment_sorted/${sample}_ReadsPerGene.out.tab | tail -n +5 | cut -f2 > ~/asn_project/alignment_sorted/tmp/${sample}.count
done

# get a list of gene ids (-f1)
tail -n +5 ~/asn_project/alignment_sorted/N_1_ReadsPerGene.out.tab | cut -f1 > ~/asn_project/alignment_sorted/tmp/geneids.txt

# combine all the columns of the count files
paste ~/asn_project/alignment_sorted/tmp/geneids.txt ~/asn_project/alignment_sorted/tmp/*.count > ~/asn_project/alignment_sorted/tmp/tmp.out

# add the header
cat <(cat ~/asn_project/alignment_sorted/tmp/header.txt | sed 's/ /\t/g') ~/asn_project/alignment_sorted/tmp/tmp.out > ~/asn_project/alignment_sorted/STAR_counts.txt

# remove the tmp folder
rm -rf ~/asn_project/alignment_sorted/tmp

I am quite new to .sh script coding and I do not see what the error is telling me to fix. Any help is appreciated.

Tommy Nguyen
  • 11
  • 1
  • 3
  • 1
    How exactly are you running ths script? the error message suggests POSIX mode – steeldriver Apr 23 '21 at 20:16
  • 2
    You might pass the whole script through `shellcheck.net` (online or download). It it quite usual for an earlier line to have an error that only manifests itself later. – Paul_Pedant Apr 23 '21 at 20:23
  • I am running the script by `sh merge_star.sh` in my school's HPC. – Tommy Nguyen Apr 23 '21 at 20:37
  • Is the line `cat <(cat ~/asn_project/alignment_sorted/tmp/header.txt | sed 's/ /\t/g')` correct, or did the site remove a '$' between the '<' and the '('? If the '$' is missing in the script itself, that might be your problem or part of it... – C. M. Apr 23 '21 at 21:33
  • @C.M., that `<( .. )` is process substitution, it makes the output of the command inside available as if in a file. If `header.txt` contains some sort of a header, it would print that (after passing through `sed). `< $( ..)` would use the output of the command inside as a filename to read – ilkkachu Apr 23 '21 at 21:42
  • Related: [Does the shebang determine the shell which runs the script?](https://unix.stackexchange.com/questions/87560/does-the-shebang-determine-the-shell-which-runs-the-script) – ilkkachu Apr 23 '21 at 21:45
  • @ilkkachu: Thanks. I knew it was a subshell, but I have not used that form before--I have always saved output to a shellvar (or a tempfile) to feed in elsewhere to avoid unexpected issues. As such, I am used to a subshell being denoted $(....). – C. M. Apr 23 '21 at 21:55

1 Answers1

5

In the comments you say you're running this script with sh merge_star.sh. This means you're using sh to run the script, but the first line (#!/bin/bash) implies it's been written for bash. On some systems sh and bash are the same, but on others they are not; and, when invoked as sh, Bash turns off some non-POSIX features, including (for versions up to 5.0) process substitution (<(...)). So it's important to use the right shell and the right invocation.

Use bash merge_star.sh or better still, make the script executable (chmod a+x merge_star.sh) and then run it directly (./merge_star.sh)

fra-san
  • 9,931
  • 2
  • 21
  • 42
roaima
  • 107,089
  • 14
  • 139
  • 261
  • `sh` on Ubuntu is `dash`. – Kusalananda Apr 23 '21 at 21:06
  • 1
    Dash would give the error message `merge_star.sh: 20: merge_star.sh: Syntax error: "(" unexpected` – ilkkachu Apr 23 '21 at 21:43
  • @ilkkachu You are correct. It is `bash` in POSIX mode. So it's not an up-to-date Ubuntu system they are on, because Ubuntu Focal uses `dash`. – Kusalananda Apr 23 '21 at 22:36
  • I did some experimenting between bash and dash, and on my system, dash balks at the <(...) syntax entirely. Not sure if this is any help or not, but I'll let the better shell scriptors make of it what they will. – C. M. Apr 23 '21 at 22:57
  • 1
    Ultimately it doesn't really matter how `sh` is linked. It's the wrong invocation and that's why it's not working – roaima Apr 24 '21 at 08:00
  • @Kusalananda, Ubuntu uses Dash _by default_, it can be changed (`dpkg-reconfigure dash`). And the [Ubuntu wiki page on that](https://wiki.ubuntu.com/DashAsBinSh) says it's been like that since Ubuntu 6.10, so they'd have to be running something really old to precede that :) But it doesn't matter, for whatever reason they're running the script with `sh`, and that process substitution doesn't work in Bash-called-as-`sh` (in most versions), nor in Dash. – ilkkachu Apr 24 '21 at 09:44