如何用逗号而不是空格分割列表

Eng*_*uad 43 linux csv bash shell split

我想一个文本用逗号分开,没有空间 in for foo in list.假设我有一个CSV_File包含以下文本的CSV文件:

Hello,World,Questions,Answers,bash shell,script
...
Run Code Online (Sandbox Code Playgroud)

我使用下面的代码将它分成几个单词:

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

它打印:

Hello
World
Questions
Answers
bash
shell
script
Run Code Online (Sandbox Code Playgroud)

但我希望它用逗号分隔文本而不是空格:

Hello
World
Questions
Answers
bash shell
script
Run Code Online (Sandbox Code Playgroud)

我怎样才能在bash中实现这一目标?

Sor*_*rin 49

IFS设置为:

sorin@sorin:~$ IFS=',' ;for i in `echo "Hello,World,Questions,Answers,bash shell,script"`; do echo $i; done
Hello
World
Questions
Answers
bash shell
script
sorin@sorin:~$ 
Run Code Online (Sandbox Code Playgroud)

  • 要在脚本中使用它,您应该将 IFS 变量恢复到以前的值。请参阅安德鲁·纽迪盖特的回答。 (2认同)

mkj*_*mkj 46

使用子shell替换来解析单词撤消所有正在进行的工作以将空格放在一起.

尝试改为:

cat CSV_file | sed -n 1'p' | tr ',' '\n' | while read word; do
    echo $word
done
Run Code Online (Sandbox Code Playgroud)

这也增加了并行性.在问题中使用子shell会强制整个子shell进程完成,然后才能开始迭代答案.管道到子壳(如我的答案)让它们并行工作.当然,只有文件中有许多行才有意义.

  • @mkj您曾经看过Val Kilmer的电影Real Genius吗?他们应该进行翻拍,但要进行更改,以使其适合您,因为您是真正的天才。 (2认同)

gle*_*man 17

我认为规范方法是:

while IFS=, read field1 field2 field3 field4 field5 field6; do 
  do stuff
done < CSV.file
Run Code Online (Sandbox Code Playgroud)

如果您不知道或不关心有多少个字段:

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 "$@"; do echo "$word"; done

done < CSV.file
Run Code Online (Sandbox Code Playgroud)


Ken*_*ent 10

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
Run Code Online (Sandbox Code Playgroud)


And*_*ate 7

创建一个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
Run Code Online (Sandbox Code Playgroud)

...这会生成以下输出:

Item: this
Item: is a
Item: list
Run Code Online (Sandbox Code Playgroud)

(注意,这个答案已根据一些反馈进行了更新)


Ash*_*eri 5

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

IFS内部字段分隔符,用于扩展后的单词拆分,并使用read builtin命令将行拆分为单词.默认值为"".

IFS是一个shell环境变量,因此它将在您的Shell脚本的上下文中保持不变,但不会保持不变,除非您导出它.另外,IFS根本不会从您的环境中继承:请参阅此gnu文章了解IFS的原因和更多信息.

你的代码写得像这样:

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

应该工作,我在命令行测试它.

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
Run Code Online (Sandbox Code Playgroud)