在 /bin/sh 中并行迭代两个列表
我有两个长度相等的列表,各个项目中没有空格:
list1="a b c"
list2="1 2 3"
我想并行迭代这两个列表,将 a 与 1、b 与 2 配对,等等:
a 1
b 2
c 3
我正在尝试支持现代便携式 Bourne shell,所以 Bash/ksh 数组不可用。 在紧要关头,向 awk 进行 shell 处理是可以接受的,但如果可能的话,我宁愿将其保留在纯 sh 中。
感谢您提供的任何指示!
I have two lists of equal length, with no spaces in the individual items:
list1="a b c"
list2="1 2 3"
I want to iterate over these two lists in parallel, pairing a with 1, b with 2, etc.:
a 1
b 2
c 3
I'm attempting to support modern portable Bourne shell, so Bash/ksh arrays aren't available. Shelling out to awk would be acceptable in a pinch, but I'd rather keep this in pure sh if possible.
Thank you for any pointers you can provide!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
可能不可移植(看看所有那些 bash-isms!),但它很容易阅读,其他人可能会发现它有用......
Probably not portable (look at all those bash-isms!), but it is easy to read and someone else might find it useful...
这应该是一个相当干净的解决方案,但除非您使用 bash 的进程替换,否则它需要使用临时文件。 我不知道这比在每次迭代中调用
cut
和sed
是好是坏。This should be a fairly clean solution, but unless you use
bash
's process substition, it requires the use of temporary files. I don't know if that's better or worse than invokingcut
andsed
over every iteration.这有点 hacky 但可以完成工作:
This is a bit hacky but does the job:
这应该是可移植的,并且也适用于两个以上的列表:
使用位置参数也可以。 请注意,列表元素不能以“-”开头。 否则“设置”将会失败。
This should be portable and also works with more than two lists:
Using positional paramers works, too. Please note, the list elements may not start with "-". Otherwise "set" will fail.
没关系,看到“谍影重重”并想到“谍影重重”。 将其留在这里是因为它可能对某人有用,但显然不是所问问题的答案,抱歉!
--
这有一些缺点(它不能优雅地处理不同大小的列表),但它适用于您给出的示例:
使用常见的 unix 工具(如 awk 和 cut)有更优雅的方法,但上面是纯粹的- bash 实现按要求
评论已接受的答案,它在 Linux 或 Solaris 中对我来说都不起作用,问题是 sed 的正则表达式中的 \S 字符类快捷方式。 我用 [^ ] 替换它并且它起作用了:
NEVERMIND, SAW "BOURNE" and thought "BOURNE AGAIN". Leaving this here because it might be useful for someone, but clearly not the answer to the question asked, sorry!
--
This has some shortcomings (it doesn't gracefully handle lists that are different sizes), but it works for the example you gave:
There are more graceful ways using common unix tools like awk and cut, but the above is a pure-bash implementation as requested
Commenting on the accepted answer, it didn't work for me in either linux or Solaris, the problem was the \S character class shortcut in the regexp for sed. I replaced it with [^ ] and it worked:
不使用数组的解决方案:
Solution not using arrays:
当第一个解决方案开始出现在这里时,我一直在研究基于 sed 的答案。 但经过进一步调查,发现列表中的项目是用换行符分隔的,而不是空格,这使我能够采用基于头和尾的解决方案:
我发布此内容是为了防止有人遇到这种变体问题,但我根据发布的问题授予接受的答案。
I had been working on a sed-based answer when the first solutions started showing up here. But upon further investigation, it turned out that the items in the list were separated by newlines, not spaces, which allowed me to go with a solution based on head and tail:
I'm posting this just in case somebody encounters this variant of the problem, but I'm awarding the accepted answer based on the problem as posted.
作为单行:
As a one liner: