Lệnh Linux lặp lại chuỗi n lần


71

Có bất kỳ lệnh Linux tích hợp nào cho phép xuất ra một chuỗi gấp n lần một chuỗi đầu vào không ??


1
Bằng "lệnh linux tích hợp" Tôi giả sử bạn có nghĩa là lệnh shell và vì bạn không đề cập đến shell nào bạn đang sử dụng, tôi giả sử đó là bash. Bạn có thể kiểm tra điều này bằng cách gõ "echo $ SHELL" vào dòng lệnh và bạn sẽ nhận được một cái gì đó tương tự như "/ bin / bash". Nếu bạn không, bạn nên chỉnh sửa câu trả lời của mình để chỉ định nội dung hiển thị. Chúc mừng :)
Adrian Petrescu

7
Tôi đã gắn thẻ câu hỏi với "bash". Tôi nghĩ thế là đủ.
GetFree

Câu trả lời:


75
adrian@Fourier:~$ printf 'HelloWorld\n%.0s' {1..5}
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$

3
Bạn có thể giải thích làm thế nào điều này hoạt động? Tôi hiểu lệnh printf vì nó giống với lệnh trong C / C ++. Nhưng tôi không hiểu cách {1..5} được mở rộng và cách thức hoạt động cùng với phần "% .0s".
GetFree

4
Đó là một chút hack :) Hãy thử chạy "printf 'HelloWorld% d \ n' 1 2 3 4 5" và nó có thể sẽ nhấp cho bạn. Cờ% .0s có nghĩa là không làm gì cả, chỉ cần ở đó để nhận các đối số. Sau đó, nếu bash nhận được nhiều đối số hơn so với định dạng định dạng, nó sẽ chỉ in ra nhiều bản sao, lấy bao nhiêu tùy ý. Vì vậy, bạn có được hiệu ứng. Đầu ra của "printf 'HelloWorld% d% d \ n' 1 2 3 4 5 6" có thể làm cho nó rõ ràng hơn nữa. Hi vọng điêu nay co ich!
Adrian Petrescu

Tôi hiểu rồi. Đó là hành vi cụ thể của printf, thứ cho phép lặp lại
GetFree

1
(Tôi nên lưu ý rằng, từ quan điểm lý thuyết thuần túy, đây có lẽ là giải pháp nhanh nhất vì nó sử dụng một lớp vỏ nguyên thủy - không phải bất kỳ quy trình bên ngoài nào. )
Adrian Petrescu

1
Có gì đặc trưng cho printflà nó sẽ liên tục áp dụng đối số dư thừa vào chuỗi định dạng "vòng lặp" for free. Theo "thừa", tôi có nghĩa là có nhiều đối số hơn %giữ chỗ.
Dennis Williamson

69

Đây là một cách cổ điển mà khá di động:

yes "HelloWorld" | head -n 10

Đây là phiên bản thông thường hơn của câu trả lời của Adrian Petrescu bằng cách sử dụng mở rộng nẹp:

for i in {1..5}
do
    echo "HelloWorld"
done

Điều đó tương đương với:

for i in 1 2 3 4 5

Đây là một phiên bản ngắn gọn và năng động hơn của câu trả lời của pike :

printf -v spaces '%*s' 10 ''; printf '%s\n' ${spaces// /ten}

Làm thế nào để bạn thoát khỏi các dòng mới khi sử dụng lệnh yes?
GetFree

3
Một cách là dẫn nó qua sed -n 'H;${x;s/\n//gp}'hoặc cách sed -n ':t;${s/\n//gp};N;bt'khác là làm echo $(yes "HelloWorld" | head -n 10)thêm khoảng trắng giữa mỗi bản sao của chuỗi. Tuy nhiên, một cách khác là đưa nó qua tr -d '\n'đó cũng loại bỏ dòng mới cuối cùng.
Dennis Williamson

2
Nó giống như Haskell trong vỏ bash: Hashell?
wchargein

4
Giải pháp đúng là khá gọn gàng
piggybox

Các yesgiải pháp chính xác là những gì tôi cần, vì tôi muốn lặp lại một lệnh (mà đầu ra dao động). Do đó:yes "$(my-command)" | head -n 2
arnsholt

14

Điều này có thể được tham số hóa và không yêu cầu biến tạm thời, FWIW:

printf "%${N}s" | sed 's/ /blah/g'

Hoặc, nếu $Nlà kích thước của một mảng bash:

echo ${ARR[@]/*/blah}

3
Đây là ngắn nhất POSIX 7 giải pháp tôi đã thấy cho đến nay kể từ seq, yes{1..5}không POSIX 7.
Ciro Santilli新疆改造中心法轮功六四事件

Bạn không nên trộn dữ liệu vào printfđịnh dạng định dạng. Nếu dữ liệu chứa các chuỗi định dạng thì sao? Đây là cách chính xác để tự động chỉ định "độ chính xác" (độ dài): printf '%*s' "$N"- tạo thói quen gửi chuỗi định dạng trong dấu ngoặc đơn để ngăn mở rộng biến ở đó.
Dennis Williamson

13

Khá nhiều cách tốt đã được đề cập. Không thể quên về tuổi già seqmặc dù:

[john @ awesome] $ cho tôi trong `seq 5`; làm tiếng vang "Hi"; xong
Chào
Chào
Chào
Chào
Chào

Điều này thực sự tôn trọng một số không, coi nó là số không! (Thủ {i..j}thuật không bao giờ trả lại một phạm vi trống.)
JellicleCat

10

Có lẽ một cách khác chung chung và hữu ích hơn cho bạn:

adrian@Fourier:~$ n=5
adrian@Fourier:~$ for (( c=1; c<=n; c++)) ; do echo "HelloWorld" ; done
HelloWorld
HelloWorld
HelloWorld
HelloWorld
HelloWorld
adrian@Fourier:~$ 

Shell bash mạnh hơn hầu hết mọi người nghĩ :)


Điều này nhận được phiếu bầu của tôi, vì nó hoàn toàn là nội bộ; không yêu cầu rèn.
esm

2
Những gì bạn đang đề cập đến? Câu trả lời ban đầu không yêu cầu. Đầu ra của 'type printf' là 'printf là shell dựng' và do đó chạy trong quy trình bash ban đầu.
CodeGnome

Đây là người duy nhất cho đến nay ( yes, printf, for i in {1..5}) mà nếu nlà số không, nó sẽ trả về chuỗi rỗng mà không tồn tại tình trạng của 1. Ngoài ra do các ký hiệu toán học để so sánh, nó rất dễ dàng để có bù đắp bằng 1 (ví dụ như bằng cách thay đổi <=để <)
Mehrad Mahmoudian

10

Bạn có thể sử dụng một mẹo. Báo lại một biến trống không in bất cứ điều gì. Vì vậy, bạn có thể viết:

echo word$wojek{1..100}

Nếu $wojek1 $wojek2... $wojek100là các biến không tồn tại, bạn sẽ nhận được từ lặp lại 100 lần mà không có gì khác.


1
Đó là một hack xấu xí xấu xí, nhưng tôi không thể không yêu nó và sử dụng nó.
16807

Yêu nó! Có thể sử dụng $_thay vì $wojeklàm cho ý định rõ ràng hơn.
Mihai Todor

7

Lặp lại nnhiều lần, chỉ cần đặt n-1dấu phẩy giữa {}:

$ echo 'helloworld'{,,}
helloworld helloworld helloworld

Lặp lại 'hellowworld' hai lần sau tiếng vang đầu tiên.


5
Đẹp, nhưng nếu tôi muốn lấy ntừ một biến thì sao?
GetFree

1
nó thêm một không gian bổ sung sau mỗi '
hellowworld

điều này dường như không cho phép bạn đặt dòng mới vào chuỗi (tức là nhận hellowworld trên dòng riêng của họ)
TankorSmash

5
awk 'BEGIN {while (c++<4) printf "Hello"}'

Kết quả

Xin chao xin chao xin chao xin chao

Sử dụng cái này mà không có awk: while ((c ++ <5)); làm printf 'xin chào'; xong
emf

4

Tôi đã trải qua các cảnh báo đường ống bị hỏng với yesgiải pháp, vì vậy đây là một giải pháp thay thế tốt khác:

$ seq 4 | sed "c foo"
foo
foo
foo
foo

3

dựa trên những gì @pike đã gợi ý

cho mỗi ký tự trong chuỗi echo chuỗi

echo ${target//?/$replace}

Một ví dụ về một tiêu đề được gạch chân với các =ký tự

export heading='ABCDEF'; 
export replace='='; 
echo -e "${heading}\n${heading//?/$replace}"

sẽ xuất

ABCDEF
======

Điều này dường như chuyển giữa linux và OS X và điều đó làm tôi hạnh phúc.

Xin chào!


3

Nếu bạn đang sử dụng BSD, bạn chỉ có thể sử dụng seq.

$ seq -f "Hello, world" 5
Hello, world
Hello, world
Hello, world
Hello, world
Hello, world

1
Trong seq (GNU coreutils) 8.25, điều này mang lại seq: format 'Hello, world' has no % directive, buộc một chỉ thị định dạng phải có mặt. GNU coreutils được sử dụng, ví dụ như nhiều bản phân phối Linux và Cygwin. Bao gồm thông tin ở đây cho những người thiếu thông tin mà nó chỉ hoạt động trong BSD seq.
Palec

2
line="==========================="
line=${line:0:10}
${line//"="/"ten "}

đầu ra

ten ten ten ten ten ten ten ten ten ten

Có thể một ví dụ dài dòng hơn: khai báo c = '-----'; c = $ {c // $ {c: 0: 1} / $ c}; echo $ c # In "-" 25 lần.
Stephen Niedzielski

2

Giả sử bạn muốn một cái gì đó giống như xtoán tử của Perl , nơi bạn không tự động nhận được một dòng mới giữa các lần lặp lại:

x() {
  # usage: x string num
  for i in $(seq 1 $2); do printf "%s" "$1"; done
  # print a newline only if the string does not end in a newline
  [[ "$1" == "${1%$'\n'}" ]] && echo ""
}

x Hi 10  # ==> HiHiHiHiHiHiHiHiHiHi

x $'Hello World!\n' 3

Tôi rõ ràng đã sử dụng một forvòng lặp bởi vì bạn không thể viết {1..$n}bằng bash: mở rộng dấu ngoặc được thực hiện trước khi thay thế biến.


2

Không được tích hợp chính xác vào linux, nhưng nếu bạn đã cài đặt python ..

python
>>>var = "string"
>>>var*n

Hoặc trong một dòng, như bình luận đề xuất:

python -c 'print "This is a test.\n" * 10'

4
Không thực sự hữu ích, vì nó không thể dễ dàng tích hợp vào các kịch bản shell, v.v. Và vì có khoảng một tỷ cách để làm điều này trong chính vỏ, tôi thấy ít lý do để đưa ra những khẩu súng lớn (ví dụ Python) cho nó .
Adrian Petrescu

7
Tôi đồng ý với quan điểm thứ hai của bạn nhưng không phải là nắm đấm ... thật dễ dàng để tích hợp vào tập lệnh shell: python -c 'print "Đây là một bài kiểm tra. \ N" * 10'
larsks

Tôi thích khả năng đọc của giải pháp này, lý do đủ tốt cho tôi. ;)
elias

2

Không có phép thuật ở đây:

seq 5 | awk '{print "Hello World"}'


1

Hãy thử cái này:

echo $(for i in $(seq 1 100); do printf "-"; done)

Sẽ tạo (một trăm dấu gạch ngang):


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.