Folgendes habe ich bisher:
#!/bin/bash
while read line; do
DB=$(echo $line | cut -f1)
USER=$(echo $line | cut -f2)
PASS=$(echo $line | cut -f3)
echo DB=$DB USER=$USER PASS=$PASS
done < users.txt
Und ein Beispiel der Eingabedatei:
drupal_1 drupal1 tmmjXSWL
drupal_2 drupal2 FHiJSYHM
drupal_3 drupal3 b7bFNj06
drupal_4 drupal4 0AaV62EL
Und Ausgabe aus dem Skript:
DB=drupal_1 drupal1 tmmjXSWL USER=drupal_1 drupal1 tmmjXSWL PASS=drupal_1 drupal1 tmmjXSWL
DB=drupal_2 drupal2 FHiJSYHM USER=drupal_2 drupal2 FHiJSYHM PASS=drupal_2 drupal2 FHiJSYHM
DB=drupal_3 drupal3 b7bFNj06 USER=drupal_3 drupal3 b7bFNj06 PASS=drupal_3 drupal3 b7bFNj06
Aus irgendeinem Grund wird jede Variable auf die gesamte Zeile gesetzt. Wenn ich echo users.txt | cut -f1
in der Befehlszeile verwende, wird das Token einwandfrei zurückgegeben.
$(echo $line | cut -d" " -f1)
funktioniert auch.Das Problem liegt im Befehl
echo $line
. Da keine Anführungszeichen vorhanden sind$line
, führt die Shell eine Wortteilung durch und interpretiert dann jedes Wort als ein Muster mit Globen. Probieren Sie es aus mitIn Ihrem Fall trennen die Tabulatoren Wörter, die dann zu getrennten Argumenten werden
echo
. Derecho
Befehl gibt seine Argumente durch ein Leerzeichen getrennt aus. Dies führtcut
dazu, dass durch Leerzeichen getrennte Felder anstelle von durch Tabulatoren getrennten Feldern empfangen werden.Setzen Sie Variablen-
$foo
und Befehlsersetzungen immer in doppelte Anführungszeichen$(foo)
(es sei denn, Sie verstehen, warum Sie sie weglassen müssen und warum dies in Ordnung ist).echo "$line"
würde hier funktionieren, aber es ist eine komplizierte Art und Weise, das zu tun, was Sie vorschlagen.Unter Beibehaltung des Parsing-Ansatzes in der Shell können Sie den
read
Befehl veranlassen, die Eingabe in Felder zu analysieren.read
Teilt Felder, die durch Zeichen getrennt sind, im Wert derIFS
Variablen auf, der standardmäßig aus einem Leerzeichen und einem Tabulator (plus einer neuen Zeile, die nicht in einer Zeile vorkommen darf) besteht. Wenn Sie nur an Registerkarten teilen möchten, legen SieIFS
zunächst eine einzelne Registerkarte fest. Beachten Sie, dass führende und nachfolgende Registerkarten ignoriert werden und aufeinanderfolgende Registerkarten als eine einzige gelten.read
behandelt\
als Sonderzeichen: ein Backslash gefolgt von einer Newline werden ignoriert;\\
wird zu einem einzelnen Backslash. Wenn Sie dieses Verhalten vermeiden möchten, übergeben Sie die-r
Option.quelle
IFS=$'\t'