"35.172.217.40 - 35.172.217.40"

Как разбить список запятой, а не пробелом

Я хочу разбить текст запятой , не пробел в for foo in list. Предположим, у меня есть CSV файл CSV_File со следующим текстом внутри него:

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

Я использовал следующий код, чтобы разбить его на несколько слов:

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

Он печатает:

Hello
World
Questions
Answers
bash
shell
script

Но я хочу, чтобы он разбивал текст запятыми, а не пробелами:

Hello
World
Questions
Answers
bash shell
script

Как я могу достичь этого в bash?

+35
источник поделиться
7 ответов

Использование подсеточной подстановки для разбора слов отменяет всю работу, которую вы делаете, чтобы сместить пробелы.

Попробуйте вместо этого:

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

Это также увеличивает parallelism. Использование подоболочки, как в вашем вопросе, заставляет весь процесс подоболочки завершить, прежде чем вы сможете начать повторять ответы. Трубопровод к подоболочке (как в моем ответе) позволяет им работать параллельно. Это имеет значение только в том случае, если у вас много строк в файле.

+38
источник

Установите IFS в:

[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]:~$ 
+43
источник

Я думаю, что канонический метод:

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

Если вы не знаете или не заботитесь о том, сколько полей есть:

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
+16
источник
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
+7
источник

Читайте: http://linuxmanpages.com/man1/sh.1.php & Амп; http://www.gnu.org/s/hello/manual/autoconf/Special-Shell-Variables.html

IFS Внутренний разделитель полей, который используется для разбиения слов после расширения и разделить строки на слова с чтением               встроенная команда. Значение по умолчанию - `` ''.

IFS - это переменная среды оболочки, поэтому она останется неизменной в контексте вашей оболочки script, но не иначе, если вы не ЭКСПОРТ. ТАКЖЕ ЗНАЙТЕ, что IFS, скорее всего, не будет унаследован от вашей среды: см. Эту запись gnu по причинам и дополнительной информации о IFS.

Вы код написан следующим образом:

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

должен работать, я тестировал его в командной строке.

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
источник

Создайте функцию bash

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

... это генерирует следующий вывод:

Item: this
Item: is a
Item: list

(Обратите внимание: этот ответ обновлен в соответствии с некоторой обратной связью)

+5
источник

Вы можете использовать:

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

или

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

Это часть, которая заменяет запятую пробелом

sed 's/,/ /g'
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос