这行代码正是这样做的,只是我希望它从第一个字符而不是第七个字符开始。
$ 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