Bash - Aynı satırdaki sayı dizisi


20

seqSatır başına bir tamsayı dizisi oluşturma komutunu biliyorum , ama iki soru sormak istiyorum:

  1. Dizinin numaralarını aynı satıra yazmak mümkün müdür?

  2. Boşluk ile ayrılmış sayı dizisinden oluşan bir dize oluşturmak mümkün müdür?


Kabuk, boşluk gibi yeni satırları bağımsız değişken ayırıcısı olarak görür. Yani, seq bir ayırıcı argüman var iken, ve söylemek daha basit bir şey sadeceecho $(seq 1 10)
user3188445

1
@ user3188445, bunu yapan split + glob operatörüdür (varsayılan olarak boşluk ve satırsonu içeren ancak değiştirilebilir IFS özel değişkenini kullanan), kabuk tarafından yapılan kelime belirteçlerinden ayrıdır.
Stéphane Chazelas

Yanıtlar:



21

GNU seqseparator ( -s) seçeneğini kullanır:

$ 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)iyi çalışıyor.

13

Tüm kabuklara ve seq'e sahip herhangi bir sisteme taşınabilir (bu sorular etiketlendiğinden)

Başlangıç ​​1 ise:

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

Aksi takdirde:

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

Bc ile:

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

Bash

echo {1..10}

Not:

Bu yankı çözümü, IFS değeri varsayılan olarak yaptığı bir yeni satır içeriyorsa çalışır.
Varsayılan olarak, IFS <boşluk ><tab> <newline> sekansına ayarlıdır . Ve kabuğun her temiz başlangıcı için sıfırlanır. Ancak, bazı aşırı köşe durumlarında değişmiş olabileceğine dair endişeleriniz varsa, birkaç çözümümüz var.

Bash, zsh, ksh altında şunu kullanın: IFS = $ '\ t \ n' (bu cevabın geri kalanını atlayın).


Bununla birlikte, IFS değerinin sh altında sıfırlanması karmaşık olabilir Tüm ayrıntıları buradan okuyun .

IFS ayarını kaldırın.

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

her zaman çalışır. Aşağıda, IFS'nin ayarlanması gereken bir komut dosyası gibi IFS gerektiren bir kod (veya alt komut dosyaları) olmaması şartıyla OldIFS="$IFS".

Doğru çözüm.

Sh için bir hile kullanma :

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

Yorumlar uzun tartışmalar için değildir; bu sohbet sohbete taşındı .
terdon

1
Çoğu sh uygulaması, ortamda bulunan IFS'i göz ardı edecektir (istisnalar, bazı kül türevleri, bazı Bourne kabuklarının çok eski versiyonları ve lüksün son versiyonlarıdır). Not sadece yapabileceği IFS='<space><tab><newline>' alanlardır <space>, <tab>, <newline>karşılık gelen edebi karakterlerdir.
Stéphane Chazelas


0
seq 10 |xargs

...veya...

seq 10 |paste -s -

Yukarıdaki komutların her ikisi de tam sayıları boşlukla ayıracaktır. xargsvarsayılan olarak taklit eder /bin/echove böylece her tamsayı tek bir boşlukla ayrılır. Bununla birlikte, varsayılan olarak en fazla 128K komut satırı uzunluğuna sahip olacaktır. Bunu ayarlayabilirsiniz ...

seq 100000 | xargs -s2093009 | wc -l

... baskılar 1. Ben -sburada değer keyfi değil - (görünüşte zaten çalıştı) daha yüksek bir değer denedikten sonra aldım ama daha sonra xargsyararlı mesajı yazdırdı:

-s value should be <2093010

pasteiki biridir (bilgi) istenilen uzunlukta hatları işlemek için araçlar POSIX onaylanmış:

pasteşartname uygulama kullanımı :

Standart yardımcı programların çoğu metin dosyaları üzerinde çalışır . Yardımcı cutprogram, rasgele satır uzunluklarına sahip dosyaları aynı verileri içeren bir metin dosyaları kümesine dönüştürmek için kullanılabilir. Yardımcı pasteprogram, rasgele satır uzunluklarına sahip dosyalar oluşturmak (veya yeniden oluşturmak) için kullanılabilir.

metin dosyaları

Sıfır veya daha fazla satır halinde düzenlenmiş karakterler içeren bir dosya. Satırlar NUL karakterleri içermez ve hiçbiri ewline karakteri {LINE_MAX}de dahil olmak üzere bayt uzunluğunu aşamaz \n. POSIX.1-2008 metin dosyaları ve ikili dosyalar arasında ayrım yapmasa da (ISO C standardına bakın) , birçok yardımcı program metin dosyaları üzerinde çalışırken yalnızca öngörülebilir veya anlamlı çıktı üretir. Böyle bir kısıtlamaya gerek standart gereçleri her zaman belirtmek metin dosyaları kendi içinde STDIN veya GİRİŞ DOSYALARI bölümleri.

pastevarsayılan olarak bir sekme sınırlayıcıdır ve böylece ikinci komutu izleyen her tamsayı arasında bir sekme olacaktır. Yapabilirsin...

seq 10 |paste -sd ' ' - 

... -dbu davranışı değiştirmek için elimiter anahtarını kullanın,


seq 10 | xargsiyi çalışıyor, ancak komut satırı sınırları nedeniyle, seq 100000 | xargs5 \nsınırlandırılmış satır çıktı (sistemimde)
Peter.O

@ Peter.O - paste and cut`, keyfi uzunluk çizgileriyle çalışmak için POSIX onaylı iki yardımcı programdır . Bununla birlikte xargs | xargs, bir seçenek. Or elseseq 100000|tr \\n \
mikeserv

Yorumlar uzun tartışmalar için değildir; bu sohbet sohbete taşındı .
terdon

@BinaryZebra - hayır değil - düşündüğünüz gibi değil. Neden $IFSbir sayı ayarlamayı denemiyorsunuz ? Ve bashyine de onun yavaş yavaş yavaşça. Cevabınızdan bahsediyorsunuz sh- $IFSbu bağlamda ayarlamanız bile gerekmiyor - eğer orada ayarlanmışsa, ortamdan geçecektir. Ve seq 100000|paste -sperformans açısından 5: 1'i geçenden daha kısa değil . Ve pastehiçbir gotchas ile gelmiyor.
mikeserv

@BinaryZebra - hadi, neden yalan söyleyeyim? Yanlış bilgiyi yaymaktan hoşlandığım için bu sitede büyük bir cevap profilim var mı? Ya da belki de insanlara yardım etmeyi seviyorum ve ben de öğrenmenin zorluğunun tadını çıkarmayı seviyorum. Hangisinin daha akla yatkın olduğunu düşünüyorsunuz? Seviyorum $IFS- her zaman kullanıyorum - ama ben ayarlamadığım sürece kullanmıyorum ve siz de yapmamalısınız. Özellikle bunu yapması gereken daha iyi bir şey bilmeyen rastgele yabancılara tavsiye etmemelisiniz. Bunu şansa bırakmayın - bu bir bilgisayar programı. Beklenmedik bir şekilde davranması bir hatadır - neden izin verilebilir?
mikeserv
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.