Bash - Folge von Zahlen in derselben Zeile

20

Ich kenne den Befehl seq, eine Folge von ganzen Zahlen pro Zeile zu generieren, möchte aber zwei Fragen stellen:

  1. Ist es möglich, die Nummern der Sequenz in dieselbe Zeile zu schreiben?

  2. Ist es möglich, eine Zeichenfolge zu erstellen, die aus einer durch ein Leerzeichen getrennten Folge von Zahlen besteht?

Salsiccio
quelle
Die Shell behandelt Zeilenumbrüche wie Leerzeichen als Argumenttrennzeichen. Also, während seq ein Separator-Argument hat und noch einfacher zu sagen istecho $(seq 1 10)
user3188445
1
@ user3188445, es ist der split + glob-Operator, der das tut (der die IFS-Spezialvariable verwendet, die standardmäßig Leerzeichen und Zeilenumbruch enthält, aber geändert werden kann). Er unterscheidet sich von der Wort-Tokenisierung, die von der Shell durchgeführt wird.
Stéphane Chazelas

Antworten:

21

GNU seqverwendet die -sOption separator ( ):

$ seq -s ' ' 1 5
1 2 3 4 5

$ var="$(seq -s ' ' 1 5)"
$ echo "$var"
1 2 3 4 5
heemayl
quelle
1
echo $(seq 5)funktioniert gut.
13

Portabel für alle Shells und alle Systeme mit seq (da diese Frage mit einem Tag versehen ist)

Wenn start 1 ist:

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

Andernfalls:

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

Mit bc:

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

In Bash

echo {1..10}

Hinweis:

Diese Echolösung funktioniert, wenn der Wert von IFS eine neue Zeile enthält, was standardmäßig der Fall ist.
Standardmäßig ist IFS auf die Reihenfolge <Leerzeichen> <Tabulator> <Zeilenvorschub> eingestellt . Und wird bei jedem Neustart der Shell zurückgesetzt. Wenn Sie jedoch befürchten, dass sich dies in einem extremen Eckfall geändert hat, haben wir verschiedene Lösungen.

Verwenden Sie unter bash, zsh, ksh einfach: IFS = $ '\ t \ n' (überspringen Sie den Rest dieser Antwort).


Das Zurücksetzen des IFS-Werts unter sh kann jedoch kompliziert sein. Lesen Sie das vollständige Detail hier .

Deaktivieren Sie IFS.

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

wird immer funktionieren. Vorausgesetzt, es gibt keinen Code darunter (oder untergeordnete Skripte), für die IFS festgelegt werden muss, wie z. B. ein Skript, das dies tut OldIFS="$IFS".

Richtige Lösung.

Mit einem Trick für sh:

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

quelle
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Terdon
1
Die meisten sh-Implementierungen ignorieren das in der Umgebung gefundene IFS (Ausnahmen sind einige Aschederivate, sehr alte Versionen einiger Bourne-Shells und neuere Versionen von posh). Beachten Sie, dass Sie einfach tun , IFS='<space><tab><newline>' wo diejenigen <space>, <tab>, <newline>sind die entsprechenden wörtlichen Zeichen.
Stéphane Chazelas
3

Benutze das:

string="$(seq -s " " 1 10)"
Cyrus
quelle
0
seq 10 |xargs

...oder...

seq 10 |paste -s -

Die beiden obigen Befehle trennen die Ganzzahlen durch Leerzeichen. xargsStandardmäßig wird imitiert, /bin/echound daher wird jede Ganzzahl durch ein einzelnes Leerzeichen getrennt. Es wird jedoch standardmäßig eine maximale Befehlszeilenlänge von 128 KB verwendet. Sie können dies einstellen ...

seq 100000 | xargs -s2093009 | wc -l

... druckt 1. Der Wert für -shier ist nicht willkürlich - ich habe ihn erhalten, nachdem ich einen höheren Wert ausprobiert habe (was anscheinend trotzdem funktioniert hat), aber anschließend xargsdie hilfreiche Meldung gedruckt:

-s value should be <2093010

pasteist meines Wissens eines von zwei POSIX-sanktionierten Dienstprogrammen für die Verarbeitung von Zeilen beliebiger Länge:

pasteVerwendung der Spezifikationsanwendung :

Die meisten Standarddienstprogramme arbeiten mit Textdateien . Mit dem cutDienstprogramm können Dateien mit beliebigen Zeilenlängen in eine Reihe von Textdateien umgewandelt werden, die dieselben Daten enthalten. Mit dem pasteDienstprogramm können Sie Dateien mit beliebigen Zeilenlängen erstellen (oder neu erstellen).

Textdateien

Eine Datei, die Zeichen enthält, die in null oder mehr Zeilen angeordnet sind. Die Zeilen enthalten keine NUL-Zeichen und keine dürfen länger als {LINE_MAX}Bytes sein, einschließlich des \newline-Zeichens. Obwohl POSIX.1-2008 nicht zwischen Textdateien und Binärdateien unterscheidet (siehe ISO C-Standard) , erzeugen viele Dienstprogramme nur vorhersehbare oder aussagekräftige Ausgaben, wenn sie mit Textdateien arbeiten. Die Standarddienstprogramme mit solchen Einschränkungen geben Textdateien immer in ihren Abschnitten STDIN oder INPUT FILES an .

pasteDer Standardwert ist ein Tabulatorbegrenzer. Nach dem zweiten Befehl wird zwischen den einzelnen Ganzzahlen ein Tabulator eingefügt. Sie können...

seq 10 |paste -sd ' ' - 

... den -dElimiter-Schalter verwenden, um dieses Verhalten zu ändern,

mikeserv
quelle
seq 10 | xargsfunktioniert gut, aber wegen der Befehlszeilenbeschränkungen werden seq 100000 | xargs5 durch \nTrennzeichen getrennte Zeilen
ausgegeben
@ Peter.O- paste and cut` sind die beiden von POSIX sanktionierten Dienstprogramme für das Arbeiten mit Zeilen beliebiger Länge. Das heißt, xargs | xargsist eine Option. Oder sonstseq 100000|tr \\n \
mikeserv
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Terdon
@BinaryZebra - nein, tut es nicht - nicht so, wie du denkst. Warum versuchen Sie es nicht $IFSmit einer Zahl? Und in bashseiner schrecklichen Langsamkeit sowieso. In deiner Antwort sprichst du darüber sh- du musst $IFSin diesem Kontext nicht einmal einstellen - es wird über die Umgebung weitergeleitet, wenn es dort eingestellt ist. Und es ist nicht kürzer als das, seq 100000|paste -swas es leistungsmäßig mit 5: 1 schlägt. Und pastekommt nicht mit irgendwelchen Fallstricken.
mikeserv
@BinaryZebra - komm schon, warum sollte ich lügen? Verfüge ich über ein umfangreiches Antwortprofil auf dieser Website, weil ich gerne Fehlinformationen verbreite? Oder liegt es vielleicht daran, dass ich gerne Menschen helfe und die Herausforderung des Lernens genieße, während ich es tue? Was halten Sie für plausibler? Ich mag es $IFS- ich benutze es die ganze Zeit - aber ich benutze es nicht, wenn ich es nicht gesetzt habe und du auch nicht. Vor allem sollten Sie es nicht zufälligen Fremden empfehlen, die es nicht besser wissen. Überlassen Sie es nicht dem Zufall - es ist ein Computerprogramm. Es ist ein Fehler, wenn es sich unerwartet verhält - warum sollte man das zulassen?
mikeserv