Bash - Chuỗi các số trong cùng một dòng


20

Tôi biết lệnh seqtạo chuỗi số nguyên, mỗi số một dòng, nhưng tôi muốn hỏi hai câu hỏi:

  1. Có thể viết các số của dãy trong cùng một dòng không?

  2. Có thể tạo một chuỗi làm bằng chuỗi các số được phân tách bằng khoảng trắng không?


Shell xử lý các dòng mới như dấu cách như dấu phân cách đối số. Vì vậy, trong khi seq có một đối số phân tách, và điều đơn giản hơn để nói chỉ làecho $(seq 1 10)
user3188445

1
@ user3188445, đó là toán tử split + global thực hiện điều đó (sử dụng biến đặc biệt IFS theo mặc định có chứa không gian và dòng mới nhưng có thể thay đổi), nó tách biệt với mã thông báo từ được thực hiện bởi trình bao.
Stéphane Chazelas

Câu trả lời:



21

GNU seq-stùy chọn separator ( ):

$ 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)hoạt động tốt

13

Di động đến tất cả hệ vỏ và bất kỳ hệ thống nào có seq (vì câu hỏi này được gắn thẻ)

Nếu bắt đầu là 1:

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

Nếu không thì:

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

Với bc:

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

Trong bash

echo {1..10}

Chú thích:

Giải pháp echo này hoạt động nếu giá trị của IFS chứa một dòng mới, theo mặc định.
Theo mặc định, IFS được đặt thành chuỗi <dấu cách> <tab> <dòng mới> . Và được thiết lập lại cho mỗi lần khởi động sạch của vỏ. Nhưng, nếu bạn có bất kỳ lo ngại rằng nó có thể đã thay đổi trong một số trường hợp góc cực đoan, chúng tôi có một số giải pháp.

Trong bash, zsh, ksh chỉ cần sử dụng: IFS = $ '\ t \ n' (bỏ qua tất cả phần còn lại của câu trả lời này).


Tuy nhiên, việc đặt lại giá trị của IFS theo sh có thể phức tạp Đọc chi tiết đầy đủ ở đây .

Bỏ đặt IFS.

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

sẽ luôn làm việc Với điều kiện là sẽ không có mã bên dưới (hoặc tập lệnh con) cần IFS được đặt, chẳng hạn như tập lệnh nào OldIFS="$IFS".

Giải pháp đúng.

Sử dụng một mẹo cho sh:

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

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
terdon

1
Hầu hết các triển khai sh sẽ bỏ qua IFS được tìm thấy trong môi trường (ngoại lệ là một số dẫn xuất tro, phiên bản rất cũ của một số vỏ Bourne và các phiên bản gần đây của posh). Lưu ý rằng bạn chỉ có thể làm IFS='<space><tab><newline>' nơi những <space>, <tab>, <newline>là các ký tự chữ tương ứng.
Stéphane Chazelas


0
seq 10 |xargs

...hoặc là...

seq 10 |paste -s -

Cả hai lệnh trên sẽ phân tách các số nguyên bằng khoảng trắng. xargsmặc định để bắt chước /bin/echovà do đó mỗi số nguyên được phân tách bằng một khoảng trắng. Mặc dù vậy, nó sẽ mặc định có độ dài dòng lệnh tối đa là 128K. Bạn có thể điều chỉnh ...

seq 100000 | xargs -s2093009 | wc -l

... bản in 1. Tôi giá trị -sở đây không phải là tùy ý - Tôi đã nhận được nó sau khi thử giá trị cao hơn (dù rõ ràng vẫn hoạt động) nhưng sau đó đã xargsin thông báo hữu ích:

-s value should be <2093010

pastelà một trong hai (theo hiểu biết của tôi) các tiện ích bị xử phạt POSIX để xử lý các dòng có độ dài tùy ý:

pastesử dụng ứng dụng đặc điểm kỹ thuật :

Hầu hết các tiện ích tiêu chuẩn làm việc trên các tập tin văn bản . Các cuttiện ích có thể được sử dụng để chuyển các tập tin với độ dài dòng tùy ý vào một tập hợp các tập tin văn bản có chứa cùng một dữ liệu. Các pastetiện ích có thể được sử dụng để tạo ra các file với độ dài dòng tùy ý (hoặc tái tạo).

tập tin văn bản

Một tệp chứa các ký tự được tổ chức thành không hoặc nhiều dòng. Các dòng không chứa các ký tự NUL và không có ký tự nào có thể vượt quá {LINE_MAX}độ dài byte, bao gồm cả \nký tự ewline. Mặc dù POSIX.1-2008 không phân biệt giữa tệp văn bản và tệp nhị phân (xem tiêu chuẩn ISO C) , nhiều tiện ích chỉ tạo ra đầu ra có thể dự đoán hoặc có ý nghĩa khi hoạt động trên tệp văn bản. Các tiện ích tiêu chuẩn có các hạn chế như vậy luôn chỉ định các tệp văn bản trong các phần STDIN hoặc INPUT FILES của chúng .

pastemặc định cho một dấu phân cách tab và do đó sẽ có một tab giữa mỗi số nguyên theo lệnh thứ hai. Bạn có thể...

seq 10 |paste -sd ' ' - 

... sử dụng công -dcụ loại bỏ để thay đổi hành vi đó,


seq 10 | xargshoạt động tốt, nhưng vì giới hạn dòng lệnh, seq 100000 | xargsxuất ra 5 \ndòng phân cách (trên hệ thống của tôi)
Peter.O

@ Peter.O - paste and cut` là hai tiện ích bị xử phạt POSIX để làm việc với các dòng có độ dài tùy ý. Điều đó nói rằng, xargs | xargslà một lựa chọn. Hoặc cách khácseq 100000|tr \\n \
mikeerv

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
terdon

@BinaryZebra - không, nó không - không như bạn nghĩ. Tại sao không thử thiết lập $IFSmột số? Và bashdù sao thì nó cũng chậm chạp. Trong câu trả lời của bạn, bạn nói về sh- bạn thậm chí không cần phải đặt $IFStrong bối cảnh đó - nó sẽ được truyền qua môi trường nếu nó được đặt ở đó. Và nó không ngắn hơn so với seq 100000|paste -snhịp đập hiệu suất 5: 1. Và pastekhông đến với bất kỳ vấn đề nào.
mikeerv

@BinaryZebra - Thôi nào, tại sao tôi lại nói dối? Tôi có một hồ sơ câu trả lời khá lớn trên trang web này vì tôi thích phổ biến thông tin sai lệch? Hoặc có thể đó là vì tôi thích giúp đỡ mọi người và thích thử thách học tập trong khi tôi làm? Mà bạn nghĩ là hợp lý hơn? Tôi thích $IFS- tôi sử dụng nó mọi lúc - nhưng tôi không sử dụng nó trừ khi tôi đặt nó và bạn cũng không nên. Đặc biệt, bạn không nên giới thiệu cho những người lạ ngẫu nhiên không biết thay thế tốt hơn nên làm như vậy. Đừng để nó có cơ hội - đó là một chương trình máy tính. Đó là một lỗi nếu nó hoạt động bất ngờ - tại sao cho phép nó có thể?
mikeerv
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.