Linux 如何按逗号而不是空格拆分列表
我想在列表中用逗号Linux 如何按逗号而不是空格拆分列表,linux,bash,shell,csv,split,Linux,Bash,Shell,Csv,Split,我想在列表中用逗号,而不是空格拆分一个文本。假设我有一个CSV文件CSV\u文件,其中包含以下文本: 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
,
而不是空格
拆分一个文本。假设我有一个CSV文件CSV\u文件
,其中包含以下文本:
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中实现这一点?使用子shell替换来解析单词将撤消所有将空格放在一起的工作 请尝试:
cat CSV_file | sed -n 1'p' | tr ',' '\n' | while read word; do
echo $word
done
这也增加了并行性。在您的问题中使用子shell会强制完成整个子shell过程,然后才能开始迭代答案。通过管道连接到子shell(如我的回答所示)可以让它们并行工作。当然,只有当文件中有很多行时,这才重要。kent$echo“你好,世界,问题,答案,bash shell,脚本”| awk-F',{for(i=1;i设置为,:
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
阅读:
&
IFS用于分词的内部字段分隔符
展开后,将行拆分为单词,并进行读取
内置命令。默认值为“`”
IFS是一个shell环境变量,因此它将在shell脚本的上下文中保持不变,除非您导出它。另外,请注意,IFS可能根本不会从您的环境中继承:有关IFS的原因和更多信息,请参阅这篇gnu文章
您的代码是这样编写的:
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
我认为标准方法是:
while IFS=, read field1 field2 field3 field4 field5 field6; do
do stuff
done < CSV.file
当IFS=时,读取字段1字段2字段3字段4字段5字段6;do
做事
完成
如果您不知道或不关心有多少字段:
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
IFS=,
边读边做
#分成一个数组
字段=($line)
对于“${field[@]}”中的单词,执行回显“$word”已完成
#或者使用位置参数
设置--$line
对于“$@”中的单词,执行回显“$word”已完成
完成
创建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
(注意,此答案已根据一些反馈更新)您可以使用:
cat f.csv | sed 's/,/ /g' | awk '{print $1 " / " $4}'
或
这是用空格代替逗号的部分
sed 's/,/ /g'
@Carl您能提供一个使用awk
的例子吗?是的,这比我建议的要好得多。+1对于l33t bash技能mkj:)甚至不需要while循环。不需要while循环,但我理解调用echo
作为更有趣命令的代理;也就是说,OP希望shell变量中的多字CSV内容与其他任意命令一起使用。这就是为什么我使用read来演示如何获得c将内容转换为shell变量。@mkj您看过瓦尔·基尔默的电影《真正的天才》吗?他们应该重拍,但要改变它,使其与您有关,因为您是真正的天才。请注意,如果输入包含换行符,则这将无法按预期工作(然后,它将在逗号上拆分,最初出现在输入中的换行符,即a、b\nc、d
将拆分为4个字段,而不是所需的3个字段)。对于Bash,我建议使用单命令作用域IFS
设置与read-a
或read-d
(cf.),但对于POSIX shell,我发现这是唯一干净、简单的解决方案。我假设,echo$word
实际上不是需要用$word来完成的真正的事情。在这种情况下,您的awk表达式是在原始问题中执行sed和tr的另一种方法。我认为Eng.Fouad希望在shell变量可以使用@mkj执行其他操作此解决方案可以作为shell变量进一步使用,例如:FOO=“你好,世界,问题,答案,bash shell,script”;BOO=$(echo$FOO | awk-F),{for(i=1;i@RomanChernyatchik那里的循环$BOO
为“bash”和“shell”生成单独的变量所以不能像OP-intendedNice那样工作!我完全忘记了IFS env变量!最干净、最内置的解决方案。这应该是答案。要在脚本中使用它,您应该将IFS变量还原为以前的值。请参阅Andrew Newdigate的答案。@Sorin:By“要在脚本中使用它”我的意思是,预期会有更多的代码,因此您希望重置IFS以避免任何意外行为。IFS的含义似乎非常广泛,所以最好是懒惰而不是不清楚。顺便说一句,如果您像运行您的答案一样运行命令,它将更改当前环境的IFS,您很容易忘记这一点,然后想知道为什么我们的shell行为非常怪异。能够通过name@glenn-jackman您是对的,canonical UNIX将使用您的第一种方法。第二种方法仅适用于bash或zsh的现代实现。bash的read
命令有一个-a
选项,用于将行中的单词读入数组:while阅读-a单词;对“${words[@]}”中的单词执行操作…
奇怪。知道为什么会发生这种情况吗?这里解释副作用是为了避免“副作用”,首先将IFS var存储在某个地方OLDIFS=$IFS
,然后执行IFS=,句子1=($句)
并最终还原IFS:IFS=$OLDIFS
。否则,这就是我搜索的答案。谢谢。@clime和Val,我已经更新了我的答案,以考虑您的反馈。它似乎工作正常,但请告诉我您的想法。我认为您的帖子现在太复杂了。修复原始代码片段并进行修改就足够了a最后给评论员一个小小的提示,但无论如何,没有什么是完美的。
echo "Hello,World,Questions,Answers,bash shell,script" | sed 's/,/ /g' | awk '{print $1 " / " $4}'
sed 's/,/ /g'