¿Por qué aparece un "error de sintaxis cerca de un token inesperado"?

¿Por qué aparece un "error de sintaxis cerca de un token inesperado"?

Tengo alrededor de 10k (aproximadamente 180x50x2) archivos CSV que quiero unir de la siguiente manera, pero el bucle for interno falla debido a algunos syntax error; No puedo ver el error enlastFile

#!/bin/bash
dir='/home/masi/CSV/'
targetDir='/tmp/'
ids=(118 119 120)
channels=(1 2)
for id in ids;

        do
        for channel in channels;

                # example filename P209C1T720-T730.csv
                lastFile="$dir'P'$id'C'$channel'T1790-T1800.csv'"
                # show warning if last file does not exist
                if [[ -f $lastFile ]]; then
                    echo "Last file "$lastFile" is missing" 
                    exit 1
                fi

                filenameTarget="$targetDir'P'$id'C'$channel'.csv'"
                cat $dir'P'$id'C'$channel'T'*'.csv' > $filenameTarget

        done;
done

Error

makeCSV.sh: line 12: syntax error near unexpected token `lastFile="$dir'P'$id'C'$channel'T1790-T1800.csv'"'
makeCSV.sh: line 12: `      lastFile="$dir'P'$id'C'$channel'T1790-T1800.csv'"'

SO: Debian 8.5
Kernel de Linux: 4.6 backports

Respuesta1

Falta un error doen el segundo bucle for:

for id in ids;

        do
        for channel in channels; do # <----- here ----

                # example filename P209C1T720-T730.csv
                lastFile="$dir'P'$id'C'$channel'T1790-T1800.csv'"
                # show warning if last file does not exist
                if [[ -f $lastFile ]]; then
                    echo "Last file "$lastFile" is missing" 
                    exit 1
                fi

                filenameTarget="$targetDir'P'$id'C'$channel'.csv'"
                cat $dir'P'$id'C'$channel'T'*'.csv' > $filenameTarget

        done;
done

Según la discusión en los comentarios, veo su confusión con la sintaxis del forbucle.

Esta es la sintaxis aproximada del forbucle:

for name in list; do commands; done

Siempre debe haber un docomando antes y ;(o una nueva línea) seguido de doneun comando después.

Aquí hay una variación con más líneas nuevas:

for name in list
do
    commands
done

Respuesta2

Está funcionando correctamente:

#!/bin/bash
dir='/home/masi/CSV/'
targetDir='/tmp/'
ids=(118 119 120)
channels=(1 2)
for id in ids ; do

        # Add do after ';'
        for channel in channels ; do

                # example filename P209C1T720-T730.csv
                lastFile="$dir'P'$id'C'$channel'T1790-T1800.csv'"
                # show warning if last file does not exist
                if [[ -f $lastFile ]] ; then
                    echo "Last file "$lastFile" is missing" 
                    exit 1
                fi

                filenameTarget="$targetDir'P'$id'C'$channel'.csv'"
                cat $dir'P'$id'C'$channel'T'*'.csv' > $filenameTarget

        done
done

Para el futuro, utilice el depurador de bash:bash -x /ruta/a/su/script.

información relacionada