2010-11-21 3 views
0

Ich habe eine Datei wie folgt aus:Wie lese ich eine Zeile einer Datei richtig in ein Array?

1234 1234 "First Name" "Last Name" 

Und ich habe eine Bash-Funktion wie folgt aus:

function somePeoples() 
{ 
    body='"id":"'$1'","num":"'$2'","name":"'$3'","lname":"'$4'"' 
    echo $body 
} 

, die in einem Bash-Skript enthalten ist, die ich in der Befehlszeile beziehen würde. Danach mache ich die folgende Funktion zu testen:

$ arr=(1234 1234 "First Name" "Last Name") 
$ somePeoples "{arr[@]}" 
$ "id":"1234","num":"1234","name":"First Name","lname":"Last Name" 
$ somePeoples "${arr[0]}" "${arr[1]}" "${arr[2]}" "${arr[3]}" 
$ "id":"1234","num":"1234","name":"First Name","lname":"Last Name" 

ist nun zurück in die Datei loslassen, die Zeilen wie diese enthält:

input.txt: 
1234 1234 "First Name" "Last Name" 
2234 2234 "Some other name" "Some other last name" 

Ich versuche, jede Zeile in der Datei über ein lesen for-Schleife mit einer begrenzten Anzahl, weil ich genau weiß, wie viele Zeilen in der Datei. Der Trick besteht darin, jede Zeile zu lesen und jede Zeile in ein Array einzufügen, das an die somePeoples-Funktion übergeben wird. Also mache ich ein Skript, das das andere Skript mit der Funktion versorgt. Sagen wir es einfach Skript der Client aufrufen und lassen Sie uns so tun, als es tatsächlich ist Looping:

the client script: 
arr=(`sed -n "1p" input.txt`) 
somePeoples "${arr[@]}" 

Aber zu meinem Entsetzen der Ausgang ist:

$ "id":"1234","num":"1234","name":""First,"lname":"Name"" 

auch versuchen, diese Erträge um das gleiche Ergebnis zu tun

somePeoples "${arr[0]}" "${arr[1]}" "${arr[2]}" "${arr[3]}" 
somePeoples `sed -n "1p" input.txt` 

Was ist der Unterschied? Wenn ich es in der Befehlszeile mit denselben Anführungszeichen austippe, funktioniert es gut, aber nicht, wenn ich die Eingabe aus der Datei lese und sie an ein Array oder direkt an die Funktion übergebe. Warum bricht es bei Leerzeichen, obwohl die Argumente zitiert werden? Und, äh, wie kann ich das verhindern?

Ich versuche tatsächlich, einen Anfragetext vorzubereiten, der an cURL im jSON-Format übergeben wird, und die Eingabeparameter sind in einer Datei enthalten, die Hunderte von Zeilen lang ist. Aber ich denke, dass das CURL-Material für diese Frage irrelevant ist, da ich das Problem durch Bash allein reproduziert habe.

Antwort

1

benötigt Wenn, wie Sie sagen, die Originaldaten-Datei im CSV-Format, dann sind Sie wahrscheinlich besser dran, etwas zu tun, einfach wie

IFS=, while read id num name lname; do 
    ... 
done <input.txt 
+0

Vielen Dank. IFS hat den Trick gemacht :) – avendael

1

Dies geht nicht wirklich auf die Frage, warum Quoting nicht funktioniert (ich nehme an, Sie versuchten einfache Anführungszeichen), aber wenn eine schnelle und schmutzige Lösung akzeptabel ist, könnten Sie die Räume in etwas anderes über regexp konvertieren, und zurück in die Räume, wenn

+0

Eigentlich glaube ich, dass ich einen Fehler gemacht habe.Die ursprüngliche Eingabedatei ist eine CSV-Datei mit angegebenen Werten pro Spalte. Ich habe Kommas in Leerzeichen umgeschrieben und, nun, ich scheitere. Danke für den Vorschlag. Ich denke, Leerzeichen sind nicht die richtigen Begrenzer für dieses Problem. – avendael

0

Ok also hier ist das, was ich tat nach dem Konvertieren der Eingabedatei in einen csv:

ORIG_IFS=$IFS 
IFS=$(echo -en ",") 
arr=(`sed -ns "1p" input.txt`) # nvm the extension 
IFS=$ORIG_IFS 
somePeoples "${arr[@]}" 

Dies ergibt die Ausgabe:

"id":"1234","num":"1234","name":""First Name"","lname":""Last Name"" 

Die angegebenen Strings double double zitiert habe. Fast in der Nähe. Vielleicht muss ich zuerst die Eingabedatei bereinigen?

sed -e 's/"//g' <input.txt> input.txt.new 

Und dann ist das, was ich verwendet habe, um endlich die Ausgabe zu bekommen, die ich will. Danke Jungs :) Ich wusste bisher nichts über IFS.

+0

Es gibt keinen Grund, 'echo' zu verwenden, um' IFS' zu setzen, einfach 'IFS =,' oder 'IFS = ',''. –

Verwandte Themen