it-swarm.com.de

So teilen Sie eine Liste nach Komma und nicht nach Leerzeichen auf

Ich möchte einen Text mit Komma , nicht mit Leerzeichen in for foo in list teilen. Angenommen, ich habe eine CSV-Datei CSV_File mit folgendem Text darin:

Hello,World,Questions,Answers,bash Shell,script
...

Ich habe folgenden Code verwendet, um ihn in mehrere Wörter aufzuteilen:

for Word in $(cat CSV_File | sed -n 1'p' | tr ',' '\n')
do echo $Word
done

Es druckt:

Hello
World
Questions
Answers
bash
Shell
script

Aber ich möchte, dass der Text durch Kommas und nicht durch Leerzeichen getrennt wird:

Hello
World
Questions
Answers
bash Shell
script

Wie kann ich das in bash erreichen?

41
Eng.Fouad

Durch die Verwendung einer Subshell-Ersetzung zum Analysieren der Wörter wird die gesamte Arbeit, die Sie zum Erstellen von Leerzeichen ausführen, rückgängig gemacht.

Versuchen Sie stattdessen:

cat CSV_file | sed -n 1'p' | tr ',' '\n' | while read Word; do
    echo $Word
done

Das erhöht auch die Parallelität. Wenn Sie eine Subshell wie in Ihrer Frage verwenden, wird der gesamte Subshell-Prozess beendet, bevor Sie die Antworten durchlaufen können. Wenn Sie zu einer Subshell weiterleiten (wie in meiner Antwort), können sie parallel arbeiten. Das ist nur wichtig, wenn Sie natürlich viele Zeilen in der Datei haben.

44
mkj

Setze IFS auf:

[email protected]:~$ IFS=',' ;for i in `echo "Hello,World,Questions,Answers,bash Shell,script"`; do echo $i; done
Hello
World
Questions
Answers
bash Shell
script
[email protected]:~$ 
47
Sorin

Ich denke, die kanonische Methode ist:

while IFS=, read field1 field2 field3 field4 field5 field6; do 
  do stuff
done < CSV.file

Wenn Sie nicht wissen, wie viele Felder es gibt,

IFS=,
while read line; do
  # split into an array
  field=( $line )
  for Word in "${field[@]}"; do echo "$Word"; done

  # or use the positional parameters
  set -- $line
  for Word in "[email protected]"; do echo "$Word"; done

done < CSV.file
17
glenn jackman
kent$  echo "Hello,World,Questions,Answers,bash Shell,script"|awk -F, '{for (i=1;i<=NF;i++)print $i}'
Hello
World
Questions
Answers
bash Shell
script
8
Kent

Erstellen Sie eine Bash-Funktion

split_on_commas() {
  local IFS=,
  local Word_LIST=($1)
  for Word in "${Word_LIST[@]}"; do
    echo "$Word"
  done
}

split_on_commas "this,is a,list" | while read item; do
  # Custom logic goes here
  echo Item: ${item}
done

... erzeugt die folgende Ausgabe:

Item: this
Item: is a
Item: list

(Beachten Sie, dass diese Antwort aufgrund einiger Rückmeldungen aktualisiert wurde.)

7

Lesen Sie: http://linuxmanpages.com/man1/sh.1.php & http://www.gnu.org/s/hello/manual/autoconf/Special-Shell-Variables .html

IFS Das interne Feldtrennzeichen, das für die Wortaufteilung verwendet wird nach der Erweiterung und um Zeilen mit dem Read .__ in Wörter zu teilen. eingebauter Befehl. Der Standardwert ist `` '.

IFS ist eine Shell-Umgebungsvariable, daher bleibt sie im Kontext Ihres Shell-Skripts unverändert, jedoch nicht anders, es sei denn, Sie exportieren es. BEACHTEN SIE AUSSERDEM, dass IFS höchstwahrscheinlich nicht von Ihrer Umgebung geerbt wird: Weitere Informationen zu IFS finden Sie in diesem gnu-Beitrag. 

Ihr Code ist so geschrieben:

IFS=","
for Word in $(cat tmptest | sed -n 1'p' | tr ',' '\n'); do echo $Word; done;

sollte funktionieren, habe ich es auf der Kommandozeile getestet.

sh-3.2#IFS=","
sh-3.2#for Word in $(cat tmptest | sed -n 1'p' | tr ',' '\n'); do echo $Word; done;
World
Questions
Answers
bash Shell
script
5
Ashley Raiteri

Sie können verwenden:

cat f.csv | sed 's/,/ /g' |  awk '{print $1 " / " $4}'

oder

echo "Hello,World,Questions,Answers,bash Shell,script" | sed 's/,/ /g' |  awk '{print $1 " / " $4}'

Dies ist der Teil, der das Komma durch Leerzeichen ersetzt

sed 's/,/ /g'
0
ozma