如何打印字符串的每第 N 个字符?

如何打印字符串的每第 N 个字符?

这行代码正是这样做的,只是我希望它从第一个字符而不是第七个字符开始。

$ echo 1234567890abcdefghijklmnopqrstuvwxy | sed 's/.\{1,7\}\(.\{0,1\}\)/\1/g'

我正在寻找的是

19gow

答案1

您实际上并没有解释您需要什么,但获得所需输出的一种方法是选择每 8 个字符。像这样的东西:

$ echo 1234567890abcdefghijklmnopqrstuvwxy | sed -E 's/(.).{0,7}/\1/g'
19gow

该替换会查找并“捕获”任何字符 ( (.)),然后将其和接下来的 7 个字符(或更少,如果剩下的字符少于 7 个)替换为自身。实际上,这会删除除每 8 个字符之外的所有字符

答案2

zsh

$ set -o extendedglob # best in ~/.zshrc
$ string=1234567890abcdefghijklmnopqrstuvwxy
$ print -r -- ${string//(#b)(?)?(#c,7)/$match[1]}
19gow

ksh93

$ string=1234567890abcdefghijklmnopqrstuvwxy
$ print -r -- "${string//@(?){,7}(?)/\1}"
19gow

bash,就像从 ksh93 和一些 ksh 的扩展 glob 运算zsh符复制的一样,其中包括,但不是替换中的 1 或反向引用。${var//pattern/replacement}@(...){x,y}(...)

无论$string包含什么字符,甚至是换行符,这些都应该有效。

POSIX 等效项:

awk '
  BEGIN {
    len = length(string = ARGV[1])
    for (i = 1; i <= len; i += 8) result = result substr(string, i, 1)
    print result
  }' "$string"

答案3

echo 1234567890abcdefghijklmnopqrstuvwxy | sed 's/\(.\{0,1\}\).\{1,7\}/\1/g'
19gow

原作是这样的:

s/               substitute
.\{1,7\}         upto 7 characters
\(.\{0,1\}\)     and then the next in a capture
/                replace by
\1               that what was captured
/g               globally, so as many times as possible

因此,将捕获组移动到前面而不是末尾正是您所要求的。

s/               substitute
\(.\{0,1\}\)     capture the first character
.\{1,7\}         match upto 7 characters
/                replace by
\1               that what was captured
/g               globally, so as many times as possible

答案4

使用 awk:

str="1234567890abcdefghijklmnopqrstuvwxy"
awk '{for (i=1;i<=length;i=i+8) printf substr($0,i,1); printf "\n"}' <<< "$str"
19gow

相关内容