Làm thế nào để tôi xây dựng một danh sách với các số như thế này?


7

Làm thế nào để tôi xây dựng một danh sách như thế này:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Nơi tôi chạy command 15hoặc một cái gì đó. Hoặc nếu tôi chỉ định 100nó sẽ làm cho nó với 100 số hoặc 10000nó sẽ làm như thế này nhưng 10000 số.

Nó phải là năm số trên mỗi dòng (như đã thấy ở trên).

Câu trả lời:


16

bạn chỉ cần làm

seq 1 n | xargs -n 5 echo

n là số bạn muốn đạt được

Nếu hệ điều hành của bạn có bash nhưng không seq, đây là một giải pháp thay thế (thx thành @cuonglm và @jimmyj cho nhận xét của họ)

echo {1..n} | xargs -n5

(bạn có thể phải cẩn thận khi đạt số lượng rất cao với số đó, tùy thuộc vào phiên bản HĐH và bash, và nếu bash thực sự cố gắng mở rộng trước hoặc trong trường hợp đó đủ thông minh để nuôi từng chút một mà không cố gắng phù hợp với toàn bộ 1..n như một chuỗi trong bộ nhớ và cung cấp tiếng vang đó ...)

Và nhờ cuonglm và StephaneChazelas, tôi thêm một giải pháp thay thế rất nặng CPU, ít hơn so với giải pháp xargs đầu tiên của tôi (trong đó xargs gọi / bin / echo, thay vì có thể sử dụng hàm dựng sẵn của vỏ, cứ sau 5 số) có lẽ tương tự như cái thứ 2 trong đó xargs không gọi echo):

printf '%s %s %s %s %s\n' {1..n}

Giải pháp thứ 2 và thứ 3 khác với giải pháp thứ nhất là vỏ đầu tiên phải mở rộng 1..n, trước khi printf (hoặc xargs) có thể bắt đầu in, nếu tôi không nhầm ... thì nó sẽ bắt đầu sau (đặc biệt là nếu n lớn) ... Và có thể đạt đến một số giới hạn (độ dài dòng hoặc bộ nhớ, tùy thuộc vào việc triển khai và HĐH) nếu n rất lớn.


2
+1 Dễ đọc hơn giải pháp của tôi. Là người đầu tiên 1trong seq 1 15là không thực sự cần thiết.
Anthon

1
echocũng không cần thiết
Hauke ​​Laging

1
Thậm chí tốt hơn:echo {1..100} | xargs -n5
jimmij

Tôi đồng ý với cả hai nhận xét, nhưng tôi rất thích để chúng ở đó: nó dễ đọc và dễ đọc hơn để cho thấy nó thực sự hoạt động như thế nào (hơn là cách nó có thể được "đánh dấu" để phù hợp với ví dụ cụ thể này bắt đầu từ 1 và chỉ hiển thị số) ^^ (dạy một người câu cá / vs / cho con cá cụ thể này)
Olivier Dulac

1
@OlivierDulac: seqchỉ trên hệ thống GNU. Bạn có thể có bashtrên * nix khác.
cuonglm

8

Tinh khiết coreutils:

$ seq 15 | paste - - - - - 
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15

Tinh khiết perl:

$ perl -e '@a=1..15; while($i<=$#a){print "@a[$i..$i+4]\n";$i+=5}'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

GNU grep ( bị đánh cắp một cách đáng xấu hổ từ @ 1_CR ):

$ echo {1..15} | grep -oP '(\d+ ){4}\d+'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Nếu bạn không phiền khi dẫn 0s:

$ echo {01..15} | fold -sw 16
01 02 03 04 05 
06 07 08 09 10 
11 12 13 14 15

Và nếu bạn làm:

$ echo {01..15} | fold -sw 16 | sed 's/0\([1-9]\) /\1 /g'
1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15

Bất kỳ trong số này có thể được tạo thành một hàm lấy một số làm đầu vào và in danh sách tương ứng. Ví dụ,

printnums(){
 seq $1 | paste - - - - - 
}

Bạn có thể chạy

$ printnums 30
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15
16  17  18  19  20
21  22  23  24  25
26  27  28  29  30

@DisplayName bạn có thể sao chép / dán các dòng từ ví dụ của tôi trực tiếp vào thiết bị đầu cuối của bạn, điều đó sẽ làm cho chức năng có sẵn cho thiết bị đầu cuối đó. Ngoài ra, thêm các dòng vào tệp khởi tạo shell của bạn ( ~/.bashrcnếu bạn đang chạy bash) và chúng sẽ có sẵn cho tất cả các thiết bị đầu cuối. Đơn $1giản chỉ là đối số đầu tiên được đưa ra cho hàm. Để biết thêm chi tiết xem tại đây .
terdon

1
Một ví dụ khác với cột:echo -e "\n"{1..100} | column -c40 -x
jimmij

@jimmij chết tiệt! Tôi biết tôi đã mất một! Tại sao không đăng nó như là một câu trả lời?
terdon

Tại sao đặt tất cả những điều này trong một câu trả lời?
Sparr

@Sparr tại sao tôi lại chia chúng ra? Nó chỉ làm xáo trộn trang web với nhiều câu trả lời hơn mức cần thiết và mùi hôi thối của đại diện.
terdon


4

Với zsh:

$ print -aC5 {1..15}
1   2   3   4   5
6   7   8   9   10
11  12  13  14  15

$ autoload zargs # if not in ~/.zshrc
$ zargs -n 5 {1..15} -- echo
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

$ printf '%s %s %s %s %s\n' {1..15}
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

(cái sau này cũng hoạt động trong các phiên bản gần đây của ksh93 hoặc bash).


2

sử dụng vòng lặp:

for x in {1..15};do echo -n "$x ";if [ $(($x%5)) -eq 0 ];then echo ; fi done

đầu ra:

1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 

if ! ((x%5)); then echohoặcif ((x%5 == 0)); then echo
Tạm dừng cho đến khi có thông báo mới.

1
có gì mới?? đây??
Hackaholic

[ $(($x%5)) -eq 0 ]dài dòng không cần thiết.
Tạm dừng cho đến khi có thông báo mới.

1
Nó không cần thiết, bạn có thể làm như thế này hoặc có thể được thực hiện theo cách của bạn theo cách khác
Hackaholic

2

Với awkbạn có thể nói:

seq 15 | awk 'ORS=NR%5?FS:RS'

Nó trở lại:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

Về cơ bản, nó thay đổi dấu tách bản ghi đầu ra (dấu phân cách dòng) bằng dấu tách trường (khoảng trắng, theo mặc định) hoặc dấu tách bản ghi (dòng mới, làm mặc định). Vì vậy, nếu số lượng dòng là nhiều 5, một dòng mới được thêm vào; mặt khác, một không gian

Tôi đã viết một lời giải thích rộng hơn trong một câu hỏi tương tự: bash / sed / awk / etc xóa mọi dòng mới khác .


1

Bạn có thể sử dụng seq, trsed:

seq 15 | tr '\n' ' ' | sed 's/\([0-9]* [0-9]* [0-9]* [0-9]* [0-9]* \)/\1\
/g'

Hoặc như một sự kết hợp tối ưu hóa các câu trả lời của Olivier, Benoit và tôi (theo ý kiến ​​của anh ấy):

seq 15 | xargs -n 5

Bạn không cần tr, sử dụng seq -s" " 15thay thế.
cuonglm

1

Tất cả các giải pháp tao nhã đã được thực hiện ... vì vậy với GNU awkbash

echo {1..15} | awk -v RS='[[:space:]]' '{ORS=NR % numcols?RT:"\n"; print}' numcols=5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15

hoặc với GNU grep

echo {1..15} | grep -oE '([[:digit:]]+[[:blank:]]+){4}[[:digit:]]+'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
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.