2016-06-29 30 views
1

Ich mache ein Bash-Skript. Ich habe 3 Variablen istShell Bash Script

VAR1=$(cat /path to my file/ | grep "string1" | awk '{ print $2 }' 
VAR2=$(cat /path to my file/ | grep "string2" | awk '{ print $2 }' 
VAR3=$(cat /path to my file/ | grep "string3" | awk '{ print $4 }' 

Mein Problem bekommen, wenn ich

echo $VAR1 
echo $VAR2 
echo $VAR3 

schreiben kann ich Werte richtig

sehen Aber wenn ich versuche, sie mögen dieses

in einer Zeile zu schreiben
echo "VAR1: $VAR1 VAR2: $VAR2 VAR3: $VAR3" 

Der Wert $VAR3 wird am Anfang der Ausgabe geschrieben, die die Werteüberschreibtund $VAR2

Ich erwarte meine Erklärung war klar. Irgendwelche Zweifel lassen Sie mich bitte

Vielen Dank und Grüße.

Rambert

+3

'cat/Pfad zu meiner Datei/| grep "string1" | awk '{print $ 2}' '==' awk '/ string1/{print $ 2}' Datei'. Keine Notwendigkeit für "Katze" oder "Grep" mit "awk". –

+0

@andlrc: echo interpretiert '\ r' dann nicht ohne' -e' – sjsam

+0

Eine Sache. Alle Variablen sind Zahlenfolgen. – RambertNala

Antwort

5

Es scheint mir, dass $VAR3\r enthält, die in einigen Muscheln wird den Cursor an den Anfang der Zeile bewegen. Verwenden Sie printf statt:

printf "VAR1: %s VAR2: %s VAR3: %s\n" "$VAR1" "$VAR2" "$VAR3" 

Beachten Sie auch, dass die Art und Weise Sie die Werte extrahieren sehr ineffizient ist und kann auf einen Aufruf zu awk reduziert werden:

read -r var1 var2 var3 _ < <(awk '/string1/ { a=$2 } 
            /string2/ { b=$2 } 
            /string3/ { c=$4 } 
             END { print(a, b, c) }' /path/to/file) 
printf "VAR1: %s VAR2: %s VAR3: %s\n" "$var1" "$var2" "$var3" 

A nitpick ist, dass Großvariablennamen für reserviert sind Umgebungsvariablen, so änderte ich alles in Kleinbuchstaben.

<(...) ist ein Prozess, Substitution und ... Schreiben auf eine „Datei“ und gibt die Dateinamen machen:

$ echo <(ls) 
/dev/fd/63 

Und command < file ist eine Umleitung Ändern der Standardeingabe von command aus der Datei zu comming file.

+0

Jetzt, da ich daran denke, 'read -rabc <<<" 1 2 3 "' wird nicht funktionieren, wenn ein Wert fehlt: 'read -rabc <<<" 1 3 "' Beachten Sie, dass zwei Leerzeichen zusammen gequetscht werden und "3" wird in "b" gespeichert. Man könnte jedoch ein anderes Trennzeichen als das Leerzeichen finden und "IFS" entsprechend verwenden: "IFS =: read -r a b c <<<" 1 :: 3 "'. Jetzt wird '3' in' c' gespeichert. (Selbst SO wird die Leerzeichen drücken, aber es ist: '<<< "1 3" ') – andlrc

+0

Sie haben Recht. Ich habe Datei mit Notepad ++ bearbeitet und ich habe auf allen Zeilen gesehen. Also, wenn ich Zeilen-Datei zu Unix konvertieren ist alles OK Ich bekomme Datei von FTP im TXT-Format, also muss ich es konvertieren und damit arbeiten – RambertNala

+0

@RambertNala Es gibt eine Million Möglichkeiten, Zeilenenden zu konvertieren :-) Siehe [So konvertieren DOS/Windows Newline (CRLF) zu Unix Newline (\ n) im Bash-Skript?] (https://stackoverflow.com/questions/2613800/how-to-convert-dos-windows-newline-crlf-to-unix-newline-n-in-bash-script) – andlrc

1

könnten Sie schreiben:

cat /path to my file/ | grep "string1" | awk '{ print $2 }' 

als

awk '/string1/{print $2}' /path/to/file 

Mit anderen Worten: Sie mit awk allein tun könnte, was Sie mit cat, grep & awk

vorhatte bekommen Also endlich:

VAR1=$(awk '/string1/{print $2}' /path/to/file) #mind the closing ')' 

In Bezug auf das Problem, mit dem Sie konfrontiert sind, sieht es aus, als ob Sie in Ihren Variablen Wagenrücklauf oder \r haben.In bash echo nicht Escape-Sequenzen ohne die -e Option interpretieren, aber die printf Option, die
[ @andlrc ] ist zwar ein guter Versuch wies darauf hin, wie er in seinem erwähnten [ answer ]

die in einigen Schalen wird der Cursor an den Anfang verschieben

Hinweise:

  1. Ein weiterer subtl Der Punkt, den Sie beachten sollten, ist die Verwendung von Variablennamen in Großbuchstaben wie VAR1 für Benutzerskripts. So ersetzen Sie es mit var1 oder so
  2. Wenn Werte auf variable Räume Zuordnung nicht erlaubt sind um =, so

    VAR1="Note there are no spaces around = sign" 
    

    ist die richtige Nutzung