如何使用bash将字符串分成两个相同长度的子字符串?


12

我想将字符串分成两半,并按顺序打印。例如:

abcdef

进入

abc
def

有没有简单的方法可以执行此操作,还是需要一些字符串处理?


您如何获得传入的字符串?变量?Stdin?其他?
杰夫·谢勒

1
在变量中。没关系,因为可以解决任何问题(stdin输入可以放在变量中)。
加百利·迭戈

这对效率很重要,特别是如果它可能是巨大的。也是为了方便。
彼得·科德斯

Answers:


16

使用参数扩展Shell算术

变量的前半部分将是:

${var:0:${#var}/2}

变量的后半部分将是:

${var:${#var}/2}

因此您可以使用:

printf '%s\n' "${var:0:${#var}/2}" "${var:${#var}/2}"

您还可以使用以下awk命令:

awk 'BEGIN{FS=""}{for(i=1;i<=NF/2;i++)printf $i}{printf "\n"}{for(i=NF/2+1;i<=NF;i++){printf $i}{printf "\n"}}'

$ echo abcdef | awk 'BEGIN{FS=""}{for(i=1;i<=NF/2;i++)printf $i}{printf "\n"}{for(i=NF/2+1;i<=NF;i++){printf $i}{printf "\n"}}'
abc
def

感谢您的回复!
加百利·迭戈

简洁优雅的解决方案。
杜迪男孩

3
您可以摆脱$((...)); 替换的offlen部分${var:off:len}已作为算术表达式求值。范例:foo=01234567; echo "${foo:0:${#foo}/2} ${foo:${#foo}/2}"。这是有据可查的,在bash 中zshksh93bash中都是一样的。
mosvy

3
注意:如果字符串的长度为奇数,则仍会将其分为两部分,但第二部分将是一个更长的字符。
peterh-恢复莫妮卡

8

split在这里使用字符串和命令替换:

var=abcdef
printf '%s\n' "$(split -n1/2 <<<$var)" "$(split -n2/2 <<<$var)"

7

另一个awk脚本可以是:

echo abcdef | awk '{print substr($0,1,length/2); print substr($0,length/2+1)}'

1
请注意,由于除法//ERE/运算符的语法含糊,并且不适用于mawk或busybox awk ,并且它()是可选的特殊情况 length(在那种情况下,那些实现仍不兼容POSIX)。使用length()length($0)这里代替length会帮助那些人。您也可以这样做awk 'BEGIN{half = int(length(ARGV[1]) / 2); print substr(ARGV[1], 1, half) ORS substr(ARGV[1], half+1)}' abcdef,即使字符串包含换行符,也可以节省管道和额外的处理并使之正常工作。
斯特凡Chazelas

1

Python 3

s = input()  # Take one line of input from stdin.
x = len(s) // 2  # Get middle of string. "//" is floor division
print(s[:x], s[x:], sep="\n")  # Print "s" up to "x", then "s" past "x", joined on newlines.

例如,

$ echo abcdef | python3 -c 's = input(); x = len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
def

如果字符串长度不是偶数,则第二行会更长。例如

$ echo abcdefg | python3 -c 's = input(); x= len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
defg
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.