如何在bash中的定界线上拆分字符串?
我将此字符串存储在一个变量中:
IN="[email protected];[email protected]"
现在,我想通过;
定界符将字符串拆分,以便我有:
ADDR1="[email protected]"
ADDR2="[email protected]"
我不一定需要 addr1
和 addr2
变量。如果它们是阵列的元素,那就更好了。
在下面的答案中提出了建议之后,我最终得到了以下内容,这就是我所追求的:
#!/usr/bin/env bash
IN="[email protected];[email protected]"
mails=$(echo $IN | tr ";" "\n")
for addr in $mails
do
echo "> [$addr]"
done
输出:
> [[email protected]]
> [[email protected]]
有一个解决方案涉及设置 internal_field_separator (ifs)to ;
。我不确定该答案发生了什么,您如何重置返回默认值?
我保留旧的 ifs
,然后还原:
IN="[email protected];[email protected]"
OIFS=$IFS
IFS=';'
mails2=$IN
for x in $mails2
do
echo "> [$x]"
done
IFS=$OIFS
btw,当我尝试
mails2=($IN)
回复: ifs
解决方案,我尝试了此操作,然后它起作用, 在循环中,中的 $ $ nther tragets n n ockets in
它有效。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
除了已经提供的奇妙答案之外,如果只是打印出您可能考虑使用
awk
的数据问题:这将字段分隔符设置为
;
,所以它可以使用循环的循环循环并相应打印。
测试:
用另一个输入
Apart from the fantastic answers that were already provided, if it is just a matter of printing out the data you may consider using
awk
:This sets the field separator to
;
, so that it can loop through the fields with afor
loop and print accordingly.Test
With another input:
输出
系统:Ubuntu 12.04.1
Output
System : Ubuntu 12.04.1
使用
set
内置来加载$@
数组:然后,让派对开始:
Use the
set
built-in to load up the$@
array:Then, let the party begin:
两个都不需要bash数组的bournis替代方案:
案例1 :保持良好而简单:将newline用作记录分离器...例如。
注意:在第一种情况下,没有任何子过程可以协助列表操纵。
想法:也许值得广泛使用NL内部,并且仅在生成最终结果外部时才转换为不同的rs。
案例2 :使用“”;作为记录分离器...例如。
在这两种情况下,在循环完成后,可以在循环内组成一个子列表。当操作内存中的列表时,这很有用,而是将列表存储在文件中。 {PS保持冷静并继续B-)}}}
Two bourne-ish alternatives where neither require bash arrays:
Case 1: Keep it nice and simple: Use a NewLine as the Record-Separator... eg.
Note: in this first case no sub-process is forked to assist with list manipulation.
Idea: Maybe it is worth using NL extensively internally, and only converting to a different RS when generating the final result externally.
Case 2: Using a ";" as a record separator... eg.
In both cases a sub-list can be composed within the loop is persistent after the loop has completed. This is useful when manipulating lists in memory, instead storing lists in files. {p.s. keep calm and carry on B-) }
在Android Shell中,大多数提出的方法无效:
有效的是:
其中
//
表示全局替换。In Android shell, most of the proposed methods just do not work:
What does work is:
where
//
means global replacement.输出:
说明:使用括号()的简单分配转换为半分离的列表,只要您在执行此操作时就具有正确的IF。循环的标准像往常一样处理该数组中的单个项目。
请注意,在变量中给出的列表必须“难”,即带有单个tick。
必须保存和恢复IF,因为Bash不会以命令与命令相同的方式对待作业。另一种解决方法是将分配包装在功能中,并使用修改的IF调用该函数。在这种情况下,不需要单独保存/还原IF。感谢您指出的“ Bize”。
Output:
Explanation: Simple assignment using parenthesis () converts semicolon separated list into an array provided you have correct IFS while doing that. Standard FOR loop handles individual items in that array as usual.
Notice that the list given for IN variable must be "hard" quoted, that is, with single ticks.
IFS must be saved and restored since Bash does not treat an assignment the same way as a command. An alternate workaround is to wrap the assignment inside a function and call that function with a modified IFS. In that case separate saving/restoring of IFS is not needed. Thanks for "Bize" for pointing that out.
这是我的答案!
为什么这种方法对我来说是“最好的”?
由于两个原因:
Here's my answer!
Why this approach is "the best" for me?
Because of two reasons:
您可以设置内部字段分隔仪(ifs)变量,然后将其分析成一个数组。当这种情况发生在命令中时,将分配给
ifs
仅发生到该单个命令的环境(read
)。然后,它根据ifs
变量值将输入解析为一个数组,然后我们可以迭代。此示例将解析一行由
;
分开的项目,将其推入数组:另一个示例是处理中的
$的整个内容,每次输入由
;
分开:You can set the internal field separator (IFS) variable, and then let it parse into an array. When this happens in a command, then the assignment to
IFS
only takes place to that single command's environment (toread
). It then parses the input according to theIFS
variable value into an array, which we can then iterate over.This example will parse one line of items separated by
;
, pushing it into an array:This other example is for processing the whole content of
$IN
, each time one line of input separated by;
:取自 :
说明:
此构造替换了
';'
的所有出现(初始//
表示全局替换) >在中使用'''
(单个空间),然后将空格删除的字符串解释为数组(这就是周围的括号所做的)。用
''
字符替换每个''
字符的语法用来替换每个';'
字符有一些常见的陷阱:
ifs =':':'; arrin =($ in);未设置IFS;
ifs = $'\ n'; arrin =($ in);未设置IF;
Taken from Bash shell script split array:
Explanation:
This construction replaces all occurrences of
';'
(the initial//
means global replace) in the stringIN
with' '
(a single space), then interprets the space-delimited string as an array (that's what the surrounding parentheses do).The syntax used inside of the curly braces to replace each
';'
character with a' '
character is called Parameter Expansion.There are some common gotchas:
IFS=':'; arrIN=($IN); unset IFS;
IFS=$'\n'; arrIN=($IN); unset IFS;
我已经看到了一些参考
剪切
命令的答案,但它们都已删除。没有人对此进行详细说明,这有点奇怪,因为我认为这是做这种类型的事情的最有用的命令之一,尤其是用于解析界限日志文件。如果将这个特定示例分为bash脚本数组,
tr
可能更有效,但是cut> cut
可以使用,如果要拉出特定的特定中间的字段。示例:
您显然可以将其放入循环中,并迭代
-f
参数以独立拉动每个字段。当您拥有具有这样的行的界限日志文件时,这将变得更有用:
剪切
能够cat
此文件并选择一个特定字段以进行进一步处理。I've seen a couple of answers referencing the
cut
command, but they've all been deleted. It's a little odd that nobody has elaborated on that, because I think it's one of the more useful commands for doing this type of thing, especially for parsing delimited log files.In the case of splitting this specific example into a bash script array,
tr
is probably more efficient, butcut
can be used, and is more effective if you want to pull specific fields from the middle.Example:
You can obviously put that into a loop, and iterate the
-f
parameter to pull each field independently.This gets more useful when you have a delimited log file with rows like this:
cut
is very handy to be able tocat
this file and select a particular field for further processing.如果您不介意立即处理它们,我喜欢这样做:
您可以使用这种循环来初始化数组,但是可能有一种更简单的方法可以做到这一点。
If you don't mind processing them immediately, I like to do this:
You could use this kind of loop to initialize an array, but there's probably an easier way to do it.
兼容答案
有很多不同的方法可以在 bash 。
但是,必须首先注意到
bash
具有许多特别功能(So-called bashisms )在任何其他 shell 。特别是, arrays , cossotiative数组和模式替换,这些 在本文中的解决方案中以及线程中的其他使用中使用,是 bashisms ,可能在许多人使用的其他 shells 下无法使用。
例如:在我的 debian gnu/linux 上,有一个标准 shell称为 dash ;我知道很多人喜欢使用另一个称为 ksh ;还有一个特殊工具,称为 busybox 带有他自己的shell Insteller( ash )。
for posix shell < /a>兼容答案,转到本答案的最后一部分!
请求的字符串
在上面的问题中要分开的字符串是:
我将使用此字符串的修改版本来确保我的解决方案对包含whitespace的字符串具有强大的功能,这可能会破坏其他解决方案:
基于 bash (版本&gt; = 4.2)
在 pure
bash
中,我们可以创建An array ,其元素由 ifs em>(输入字段分离器)。 IFS除其他外,告诉bash
在定义数组时应将其视为元素之间的分界符:在
bash
的较新版本中使用IFS定义更改该命令仅的IFS,然后将其重置为以前的值。这意味着我们只需一行即可完成以上操作:我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" [[ $2 ]] && printf "> [%s]\n" "$dest" } mapfile <<<"${1//;/cut
, by field 1 forks >,对于少于1'000字段!准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C iterMF }cut
, by field 1 forks >,对于少于1'000字段!准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field 1 forks >,对于少于1'000字段!或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\n'} # drop '\n' added on last field, by '<<<'cut
, by field 1 forks >,对于少于1'000字段!使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
\t\n'cut
, by field 1 forks >,对于少于1'000字段!我们可以看到,中的字符串
已存储在名为
fields
的数组中,在半olons上分开:(我们可以还使用
声明-p
:)请注意,
读取
是最快进行分割的方法,因为没有< em> forks 或调用外部资源。定义数组后,您可以使用一个简单的循环来处理每个字段(或者,您现在定义的数组中的每个元素):
或者可以在使用移动后处理后从数组中删除每个字段方法,我喜欢的方法:
如果您只想简单地打印数组,您甚至不需要循环浏览它:
更新:最近 bash &gt; = 4.4
在
bash
的较新版本中,您也可以使用命令mapfile
:此语法保留特殊的chars ,新线和空字段!
如果您不想包含空字段,则可以执行以下操作:
使用
mapfile
,您还可以跳过划界元素上声明数组并隐式“循环”,每个元素都在每个元素上调用一个函数:(注意:格式字符串末端的
\ 0
,如果您不在字符串末端关心空字段,或者它们不存在。)但是您甚至可以使用 newline (mapfile的默认值)分隔符:
或您可以使用
&lt;&lt;&lt;&lt;
,并且在功能中包括一些处理,以删除newline IT添加:基于 shell
如果您不能使用
bash
或如果您想编写可以在许多不同的外壳中使用的东西,那么您经常 use bashisms - 这包括我们在上述解决方案中使用的数组。但是,我们不需要使用数组来循环浏览字符串的“元素”。许多壳中使用了一种语法,用于从 first 或最后一个中删除字符串的子字符串。请注意,
*
是一个代表零或更多字符的通配符:(,在任何解决方案中缺乏此方法是我写这个答案的主要原因;)
到目前为止 href =“ https://stackoverflow.com/posts/comments/47972612?noredirect=1”> score_under :
使用上述语法,我们可以创建一种方法,通过在定界符之前或之后删除子字符串,从字符串中提取子字符串“元素”。
下面的代码块在 bash (包括mac os的
bash ), dash , ksh , yash> yash << /a>, zsh 和 busybox 's ash :(
感谢 adam katz '使此循环变得更简单!)
为什么不
剪切
?剪切
对于在大文件中提取列很有用,但是 forks 重复(var = $(echo ... | cut ... cut ...)
)迅速过度杀伤!这是一个正确的语法,在许多 posix shell 使用
剪切
,如 dougw << /a>:比较执行时间。
准备999个字段:
然后
使用 1 forks
cut
, by field 1 forks >,对于少于1'000字段!Compatible answer
There are a lot of different ways to do this in bash.
However, it's important to first note that
bash
has many special features (so-called bashisms) that won't work in any other shell.In particular, arrays, associative arrays, and pattern substitution, which are used in the solutions in this post as well as others in the thread, are bashisms and may not work under other shells that many people use.
For instance: on my Debian GNU/Linux, there is a standard shell called dash; I know many people who like to use another shell called ksh; and there is also a special tool called busybox with his own shell interpreter (ash).
For posix shell compatible answer, go to last part of this answer!
Requested string
The string to be split in the above question is:
I will use a modified version of this string to ensure that my solution is robust to strings containing whitespace, which could break other solutions:
Split string based on delimiter in bash (version >=4.2)
In pure
bash
, we can create an array with elements split by a temporary value for IFS (the input field separator). The IFS, among other things, tellsbash
which character(s) it should treat as a delimiter between elements when defining an array:In newer versions of
bash
, prefixing a command with an IFS definition changes the IFS for that command only and resets it to the previous value immediately afterwards. This means we can do the above in just one line:We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" [[ $2 ]] && printf "> [%s]\n" "$dest" } mapfile <<<"${1//;/cut
, by field, for less than 1'000 fields!!Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C iterMF }cut
, by field, for less than 1'000 fields!!Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" printf "Seq: %6d: Sending mail to '%s'..." $seq "$dest" # mail -s "This is not a spam..." "$dest" </path/to/body printf "\e[3D, done.\n" } mapfile <<<"$IN" -td \; -c 1 -C myPubliMail # Renders the same output: # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'}" -tc 1 -C myPubliMail # Seq: 0: Sending mail to '[email protected]', done. # Seq: 1: Sending mail to '[email protected]', done. # Seq: 2: Sending mail to 'Full Name <[email protected]>', done.cut
, by field, for less than 1'000 fields!!Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\n'} # drop '\n' added on last field, by '<<<'cut
, by field, for less than 1'000 fields!!With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
\t\n'cut
, by field, for less than 1'000 fields!!We can see that the string
IN
has been stored into an array namedfields
, split on the semicolons:(We can also display the contents of these variables using
declare -p
:)Note that
read
is the quickest way to do the split because there are no forks or external resources called.Once the array is defined, you can use a simple loop to process each field (or, rather, each element in the array you've now defined):
Or you could drop each field from the array after processing using a shifting approach, which I like:
And if you just want a simple printout of the array, you don't even need to loop over it:
Update: recent bash >= 4.4
In newer versions of
bash
, you can also play with the commandmapfile
:This syntax preserve special chars, newlines and empty fields!
If you don't want to include empty fields, you could do the following:
With
mapfile
, you can also skip declaring an array and implicitly "loop" over the delimited elements, calling a function on each:(Note: the
\0
at end of the format string is useless if you don't care about empty fields at end of the string or they're not present.)But you could even use newline (mapfile's default) separator:
Or you could use
<<<
, and in the function body include some processing to drop the newline it adds:Split string based on delimiter in shell
If you can't use
bash
, or if you want to write something that can be used in many different shells, you often can't use bashisms -- and this includes the arrays we've been using in the solutions above.However, we don't need to use arrays to loop over "elements" of a string. There is a syntax used in many shells for deleting substrings of a string from the first or last occurrence of a pattern. Note that
*
is a wildcard that stands for zero or more characters:(The lack of this approach in any solution posted so far is the main reason I'm writing this answer ;)
As explained by Score_Under:
Using the above syntax, we can create an approach where we extract substring "elements" from the string by deleting the substrings up to or after the delimiter.
The codeblock below works well in bash (including Mac OS's
bash
), dash, ksh, lksh, yash, zsh, and busybox's ash:(Thanks to Adam Katz's comment, making this loop a lot simplier!)
Why not
cut
?cut
is useful for extracting columns in big files, but doing forks repetitively (var=$(echo ... | cut ...)
) become quickly overkill!Here is a correct syntax, tested under many posix shell using
cut
, as suggested by This other answer from DougW:Comparing execution time.
Preparing 999 fields:
Then
Where overall execution time is something like 49x longer, using 1 forks to
cut
, by field, for less than 1'000 fields!!这对我有用:
This worked for me:
我认为 awk 是解决问题的最佳和有效命令。默认情况下,几乎每个Linux发行版都包含尴尬。
当然,您可以
通过重新定义尴尬打印字段来存储每个电子邮件地址。
I think AWK is the best and efficient command to resolve your problem. AWK is included by default in almost every Linux distribution.
will give
Of course your can store each email address by redefining the awk print field.
该方法如何:
source
How about this approach:
Source
这也有效:
要小心,此解决方案并不总是正确的。如果您通过“ 对add1和add2均可进行。
This also works:
Be careful, this solution is not always correct. In case you pass "[email protected]" only, it will assign it to both ADD1 and ADD2.
Darron的答案我这样做:
A different take on Darron's answer, this is how I do it:
如果您不使用数组,该衬里怎么样:
How about this one liner, if you're not using arrays:
在bash中,即使您的变量包含newlines:
look:
工作的诀窍是使用
read (定界符)带有一个空的定界符,因此
-d
选项读取
被迫读取其馈送的所有内容。而且,我们将读取添加中的变量的内容,借助printf
,没有尾随的新线。请注意,这也是我们还将定界符放在printf
中,以确保将字符串传递到read
具有落后定界符。没有它,读取
将修剪潜在的尾随空字段:保留了尾随的空字段。
BASH≥4.4的更新
由于Bash 4.4,因此内置
mapfile
(akareadarray
)支持> -D
选项,以指定定界符。因此,另一种规范的方式是:In Bash, a bullet proof way, that will work even if your variable contains newlines:
Look:
The trick for this to work is to use the
-d
option ofread
(delimiter) with an empty delimiter, so thatread
is forced to read everything it's fed. And we feedread
with exactly the content of the variablein
, with no trailing newline thanks toprintf
. Note that's we're also putting the delimiter inprintf
to ensure that the string passed toread
has a trailing delimiter. Without it,read
would trim potential trailing empty fields:the trailing empty field is preserved.
Update for Bash≥4.4
Since Bash 4.4, the builtin
mapfile
(akareadarray
) supports the-d
option to specify a delimiter. Hence another canonical way is:如果您只有一个结肠,则不设置IF,
您可以做到:
您将得到:
Without setting the IFS
If you just have one colon you can do that:
you will get:
这是一个干净的3线:
其中
ifs
基于分隔符的划界单词和()
用于创建 array 。然后,[@]
用于将每个项目作为单独的单词返回。如果您之后有任何代码,您还需要还原
$ ifs
,例如未设置IFS
。Here is a clean 3-liner:
where
IFS
delimit words based on the separator and()
is used to create an array. Then[@]
is used to return each item as a separate word.If you've any code after that, you also need to restore
$IFS
, e.g.unset IFS
.这么多的答案和如此多的复杂性。尝试一个更简单的解决方案:
tr
(读取,翻译)将第一个参数替换为输入中的第二个参数。因此
So many answers and so many complexities. Try out a simpler solution:
tr
(read, translate) replaces the first argument with the second argument in the input.So
tr
, "\n" replace the comma with new line character in the input and it becomes:以下bash/zsh函数将其第一个参数分配在第二个参数给出的定界符上:
例如,命令
产生的
输出可能会将其管道输送到其他命令。示例:
与给出的其他解决方案相比,该解决方案具有以下优点:
ifs
并不是过度的:由于局部变量的动态范围,覆盖了 ,循环导致新值泄漏到从循环内执行的函数调用。不使用数组:使用
读取
在bash中读取 -a 的 -a 在zsh中需要flag -a 。如果需要,可以将功能放入脚本中,如下所示:
The following Bash/zsh function splits its first argument on the delimiter given by the second argument:
For instance, the command
yields
This output may, for instance, be piped to other commands. Example:
Compared to the other solutions given, this one has the following advantages:
IFS
is not overriden: Due to dynamic scoping of even local variables, overridingIFS
over a loop causes the new value to leak into function calls performed from within the loop.Arrays are not used: Reading a string into an array using
read
requires the flag-a
in Bash and-A
in zsh.If desired, the function may be put into a script as follows:
有这样一个简单而聪明的方式:
但是您必须使用GNU Xargs,BSD Xargs Cath Cath Cath -D DeLim。如果您使用像我这样的苹果Mac。您可以安装GNU Xargs:
然后
There is a simple and smart way like this:
But you must use gnu xargs, BSD xargs cant support -d delim. If you use apple mac like me. You can install gnu xargs :
then
在许多情况下应用尴尬
您也可以
you can apply awk to many situations
also you can use this
这里有一些很酷的答案(尤其是错误的),但是对于类似于其他语言的东西,这是我最初的问题的意思 - 我对此进行了解决:
现在
$ {a [a [0] }
,$ {a [1]}
等,如您所期望的。使用$ {#a [*]}
用于术语数。当然,要进行迭代:重要说明:
这在无需担心空间的情况下起作用,这解决了我的问题,但可能无法解决您的问题。在这种情况下,请使用
$ ifs
解决方案。There are some cool answers here (errator esp.), but for something analogous to split in other languages -- which is what I took the original question to mean -- I settled on this:
Now
${a[0]}
,${a[1]}
, etc, are as you would expect. Use${#a[*]}
for number of terms. Or to iterate, of course:IMPORTANT NOTE:
This works in cases where there are no spaces to worry about, which solved my problem, but may not solve yours. Go with the
$IFS
solution(s) in that case.这是最简单的方法。
This is the simplest way to do it.
如果没有空间,为什么不这样做呢?
If no space, Why not this?
简单答案:
样本输出:
Simple answer:
Sample output: