重击-同一行中的数字序列


20

我知道seq生成整数序列的命令,每行一个,但是我想问两个问题:

  1. 是否可以在同一行中写入序列号?

  2. 是否可以创建由空格分隔的数字序列组成的字符串?


外壳将换行符像空格一样当作参数分隔符。因此,虽然seq具有分隔符参数,但更简单的说法是echo $(seq 1 10)
user3188445

1
@ user3188445,这是split + glob运算符(使用IFS特殊变量,默认情况下确实包含空格和换行符,但可以更改),它与shell进行的单词标记化分开。
斯特凡Chazelas

Answers:



21

GNU使用seq分隔符(-s)选项:

$ seq -s ' ' 1 5
1 2 3 4 5

$ var="$(seq -s ' ' 1 5)"
$ echo "$var"
1 2 3 4 5

1
echo $(seq 5)工作良好。

13

可移植到所有shell和具有seq的任何系统(因为此问题已标记)

如果开始是1:

$ echo $(seq 10)
1 2 3 4 5 6 7 8 9 10

除此以外:

$ echo $(seq 5 10)
5 6 7 8 9 10

与公元前:

$ echo $(echo "for (i=0;i<=1000;i++) i"| bc)

重击

echo {1..10}

注意:

如果IFS的值包含换行符(默认情况下会执行换行符),则此回显解决方案有效。
默认情况下,IFS设置为序列<space> <tab> <newline>。并为每次干净启动外壳重置。但是,如果您担心它在某些极端情况下可能已更改,我们有几种解决方案。

在bash,zsh,ksh下仅使用:IFS = $'\ t \ n'(跳过此答案的所有其余部分)。


但是,在sh下重置IFS的值可能很复杂。在此处阅读完整的详细信息

取消设置IFS。

$ unset IFS; echo $(seq 5 10)                           #Always work.

将始终有效。前提是下面没有需要设置IFS的代码(或子脚本),例如OldIFS="$IFS"

正确的解决方案。

对sh 使用技巧

sh -c 'IFS="$(printf " \t\nx")"; IFS="${IFS%x}"; printf "$IFS"|xxd'  # correct.

评论不作进一步讨论;此对话已转移至聊天
terdon

1
大多数sh实现将忽略在环境中找到的IFS(例外是一些ash派生类,某些Bourne shell的非常旧的版本以及posh的最新版本)。需要注意的是,你可以简单地做IFS='<space><tab><newline>' 在那里的<space><tab><newline>有相应的文字字符。
斯特凡Chazelas


0
seq 10 |xargs

...要么...

seq 10 |paste -s -

上面的两个命令都将用空格分隔整数。xargs默认为模仿/bin/echo,因此每个整数都由一个空格分隔。但是,它将默认为最大命令行长度128K。你可以调整这个...

seq 100000 | xargs -s2093009 | wc -l

...打印1.我-s这里的值不是任意的-我尝试了更高的值(显然仍然有效)后得到了它,但随后xargs打印了有用的消息:

-s value should be <2093010

paste(据我所知) POSIX认可的用于处理任意长度的行的两种实用程序之一:

paste规范应用用法

大多数标准实用程序都可以处理文本文件。该cut实用程序可用于将任意行长的文件转换为一组包含相同数据的文本文件。该paste实用程序可用于创建(或重新创建)具有任意行长的文件。

文字档

包含以零行或更多行组织的字符的文件。这些行不包含NUL字符,并且{LINE_MAX}长度都不能超过字节,包括\newline字符。尽管POSIX.1-2008不能区分文本文件和二进制文件(请参阅ISO C标准),但是许多实用程序在对文本文件进行操作时只能产生可预测或有意义的输出。具有此类限制的标准实用程序始终在其STDININPUT FILES部分中指定文本文件

paste默认为制表符定界符,因此第二个命令后的每个整数之间将有一个制表符。您可以...

seq 10 |paste -sd ' ' - 

...使用-delimiter开关更改该行为,


seq 10 | xargs 效果很好,但是由于命令行限制,seq 100000 | xargs\n在我的系统上输出了5 条
分隔线

@ Peter.O- paste and cut`是POSIX认可的两个用于处理任意长度行的实用程序。也就是说,xargs | xargs是一种选择。否则seq 100000|tr \\n \
mikeserv

评论不作进一步讨论;此对话已转移至聊天
terdon

@BinaryZebra-不,不是-不像您认为的那样。为什么不尝试设置$IFS为数字?而且bash无论如何它缓慢的速度。在您的回答中,您谈论的是sh-您甚至不需要$IFS在该上下文中进行设置-如果在该环境中进行设置,它将通过环境传递。而且它不比seq 100000|paste -s在性能方面胜过5:1的时间短。而且paste没有任何陷阱。
mikeserv

@BinaryZebra-来吧,我为什么要说谎?我喜欢散布错误信息,因此在此站点上有大量答案资料吗?也许是因为我喜欢帮助人们并享受学习时所面临的挑战?您认为哪个更合理?我喜欢$IFS -我一直都在使用它-但是除非设置了它,否则不会使用它,您也不会使用。特别是,您不应该向不知道任何更好方法的随机陌生人推荐。不要碰碰运气-它是一个计算机程序。如果它的行为异常,那就是一个错误-为什么要允许它呢?
mikeserv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.