web-dev-qa-db-fra.com

Comment concaténer des chaînes dans un script bash pour les utiliser dans l'instruction SQL?

Je voudrais faire ce qui suit dans un script bash:

  1. lire des noms de fichiers dans un fichier avec des noms de fichiers
  2. définir un chemin d'entrée variable
  3. concat 1. et 2.
  4. utilisez 3. dans sql-statement

Voici mon code:

 #!/bin/bash
 INPath="/home/bono/RD/BV-OUT/"

 while 
 read line
 do
 RD="$line"
 RDFile="$INPath$RD"

 echo -e $RDFile

 ###MYSQLs:
 mysql -u root -D RD --local-infile << EOF
   LOAD DATA LOCAL INFILE '$RDFile'
     INTO TABLE bv_tmp_all FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n';
 EOF
 ##### EOSQL

 done < /home/bono/RD/BV-OUT/allto468

L'écho montre le chemin correct et le filenamen mais mysql dit toujours:

not found (Errcode: 2 - File or Directory not found)  

J'ai essayé différentes manières de concatter les deux chaînes mais aucune n'a fonctionné :(

Le code suivant fonctionne avec mysql (sans le concate) mais ce n'est pas ce dont j'ai besoin:

 #!/bin/bash

 while 
 read line
 do

 RDFile="/home/bono/RD/BV-OUT/468-R11"

 echo -e $RDFile

 ###MYSQLs:
 mysql -u root -D RD --local-infile << EOF
   LOAD DATA LOCAL INFILE '$RDFile'
     INTO TABLE bv_tmp_all FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n';
 EOF
 ##### EOSQL

 done < /home/bono/RD/BV-OUT/allto468

Quel est le problème avec le concate?

3
Bono

Si le allto468 lui-même a des fins de lignes, alors $ line ressemblera à 468-R11\r et ce fichier n’aura sûrement pas été trouvé.

Solutions

  1. exécutez dos2unix sur le fichier allto468 pour résoudre le problème une fois,
  2. remplacez la ligne done par

    done < <(sed 's/\r$//' /home/bono/RD/BV-OUT/allto468)
    
2
glenn jackman

Il semble que RDFile n'existe pas dans votre premier script. Qu'est-ce que vous avez dans /home/bono/RD/BV-OUT/allto468? S'agit-il de noms de fichiers qui existent vraiment dans /home/bono/RD/BV-OUT/?

J'ajouterais un test au milieu pour vérifier si le chemin construit existe vraiment, par exemple comme ceci:

#!/bin/bash
INPath="/home/bono/RD/BV-OUT/"

while read line; do
    RD="$line"
    RDFile="$INPath$RD"
    echo $RDFile

    if ! test -f "$RDFile"; then
        echo error: file does not exist: $RDFile
        continue
    fi

    ###MYSQLs:
    mysql -u root -D RD --local-infile << EOF
LOAD DATA LOCAL INFILE '$RDFile'
 INTO TABLE bv_tmp_all FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n';
EOF
    ##### EOSQL
done < /home/bono/RD/BV-OUT/allto468
3
janos

Cela ressemble à un problème de citation pour moi. Pour que la substitution de variable fonctionne, utilisez '"' et non" '", c'est-à-dire, remplacez:

mysql -u root -D RD --local-infile << EOF  
LOAD DATA LOCAL INFILE '$RDFile'  
INTO TABLE bv_tmp_all FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n';  
EOF  

avec:

mysql -u root -D RD --local-infile << EOF
LOAD DATA LOCAL INFILE "$RDFile"
INTO TABLE bv_tmp_all FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n';
EOF

Pour vérifier les caractères amusants dans le nom du fichier, echo "$RDFile" | od -bc.

0
waltinator