Làm thế nào để tách một chuỗi trong hai chuỗi con có cùng độ dài bằng cách sử dụng bash?


12

Tôi muốn chia một chuỗi thành hai nửa và in chúng liên tục. Ví dụ:

abcdef

vào

abc
def

Có một cách đơn giản để làm điều đó, hoặc nó cần một số xử lý chuỗi?


Làm thế nào để bạn có chuỗi đến? Biến đổi? Stdin? Khác?
Jeff Schaller

1
Trong một biến. Nó không thực sự quan trọng, vì bất cứ điều gì cũng có thể được giải quyết (đầu vào stdin có thể được đặt trong một biến).
Gabriel Diego

Nó quan trọng đối với hiệu quả, đặc biệt là nếu nó có thể - khổng lồ. Và cũng để thuận tiện.
Peter Cordes

Câu trả lời:


16

Sử dụng mở rộng tham sốsố học shell :

Nửa đầu của biến sẽ là:

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

Nửa sau của biến sẽ là:

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

vì vậy bạn có thể sử dụng:

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

Bạn cũng có thể sử dụng lệnh awk sau:

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

Cảm ơn vì sự trả lời!
Gabriel Diego

giải pháp súc tích và thanh lịch.
Cậu bé Dudi

3
Bạn có thể thoát khỏi $((...)); các offlenmột phần của ${var:off:len}thay đã được đánh giá là biểu thức số học. Ví dụ : foo=01234567; echo "${foo:0:${#foo}/2} ${foo:${#foo}/2}". Đó là ghi nhận, và nó giống nhau ở zshksh93như trong bash.
mosvy

3
Lưu ý: Nếu độ dài của chuỗi là số lẻ, phần này vẫn sẽ chia thành hai phần, nhưng phần thứ hai sẽ dài hơn một ký tự.
peterh - Phục hồi Monica

8

Sử dụng split, ở đây chuỗi và thay thế lệnh:

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

7

Một awkkịch bản khác có thể là:

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

1
Lưu ý rằng nó không hoạt động với mawk hoặc busybox awk vì sự mơ hồ cú pháp của phép chia //ERE/toán tử và trường hợp đặc biệt ()là tùy chọn cho length(vẫn là các triển khai đó không tuân thủ POSIX trong trường hợp đó). Sử dụng length()hoặc length($0)ở đây thay vì lengthsẽ giúp cho những người. Bạn cũng có thể làm điều awk 'BEGIN{half = int(length(ARGV[1]) / 2); print substr(ARGV[1], 1, half) ORS substr(ARGV[1], half+1)}' abcdefđó sẽ tiết kiệm đường ống và quá trình bổ sung và làm cho nó hoạt động ngay cả khi chuỗi chứa các ký tự dòng mới.
Stéphane Chazelas

1

Con trăn 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.

Ví dụ,

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

Nếu độ dài chuỗi không phải là số chẵn, dòng thứ hai sẽ dài hơn. Ví dụ

$ echo abcdefg | python3 -c 's = input(); x= len(s) // 2; print(s[:x], s[x:], sep="\n")'
abc
defg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.