Wie erstelle ich eine Liste mit solchen Zahlen?

7

Wie erstelle ich eine Liste wie folgt:

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

Wo ich renne command 15oder so. Oder wenn ich es spezifiziere 100, würde es mit 100 Zahlen kommen oder 10000und es würde es so machen, aber 10000 Zahlen.

Es sollten fünf Zahlen in jeder Zeile sein (wie oben gezeigt).

Anzeigename
quelle

Antworten:

16

du tust es einfach

seq 1 n | xargs -n 5 echo

n ist die Nummer, die Sie erreichen möchten

Wenn Ihr Betriebssystem bash, aber nicht seq hat, ist hier eine Alternative (danke an @cuonglm und @jimmyj für ihre Bemerkungen)

echo {1..n} | xargs -n5

( Je nach Betriebssystem und Bash-Version müssen Sie möglicherweise vorsichtig sein, wenn Sie mit diesem eine sehr hohe Zahl erreichen, und wenn Bash tatsächlich zuerst versucht hat, zu expandieren, oder wenn dies der Fall ist, ist es klug genug, nach und nach zu füttern, ohne zu versuchen, das Ganze zu passen 1..n als String im Speicher und füttere das Echo ...)

Und dank cuonglm und StephaneChazelas füge ich eine Alternative hinzu, die sehr, sehr wenig CPU-schwer ist als meine erste xargs-Lösung (bei der xargs alle 5 Zahlen / bin / echo aufruft, anstatt die integrierte Shell verwenden zu können) (es ist) wahrscheinlich ähnlich dem zweiten, bei dem xargs kein Echo aufruft):

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

Diese 2. und 3. Lösung unterscheiden sich von der 1. darin, dass die Shell zuerst 1..n erweitern muss, bevor printf (oder xargs) mit dem Drucken beginnen kann, wenn ich mich nicht irre ... also beginnt sie später (insbesondere wenn n ist) groß) ... und könnte einige Grenzen erreichen (Zeilenlänge oder Speicher, abhängig von der Implementierung und dem Betriebssystem), wenn n sehr groß ist.

Olivier Dulac
quelle
2
+1 Weitaus besser lesbar als meine Lösung. Das erste 1in seq 1 15ist nicht wirklich notwendig.
Anthon
1
echoist auch nicht notwendig.
Hauke ​​Laging
1
Noch besser:echo {1..100} | xargs -n5
Jimmy
Ich stimme beiden Bemerkungen zu, aber ich lasse sie lieber dort: Es ist weitaus lesbarer und tragbarer, um zu zeigen, wie es wirklich funktioniert (als nur, wie es "golfskriptiert" werden könnte, um zu diesem speziellen Beispiel zu passen, beginnend bei 1 und nur mit Zahlen). ^^ (Bringe einer Person bei, diesen bestimmten Fisch zu fischen / vs / zu geben)
Olivier Dulac
1
@OlivierDulac: seqist nur auf dem GNU-System. Sie können bashauf anderen * nix haben.
Cuonglm
8

Rein coreutils:

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

Pure 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 (schamlos von @ 1_CR gestohlen ):

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

Wenn es Ihnen nichts ausmacht, Nullen zu führen:

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

Und wenn Sie dies tun:

$ 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

Jede dieser Funktionen kann zu einer Funktion gemacht werden, die eine Zahl als Eingabe verwendet und die entsprechende Liste druckt. Zum Beispiel,

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

Sie können dann laufen

$ 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
terdon
quelle
@DisplayName Sie können die Zeilen aus meinem Beispiel direkt in Ihr Terminal kopieren / einfügen, um die Funktion für dieses Terminal verfügbar zu machen. Alternativ können Sie die Zeilen zur Initialisierungsdatei Ihrer Shell hinzufügen ( ~/.bashrcwenn Sie bash ausführen), damit sie allen Terminals zur Verfügung stehen. Dies $1ist einfach das erste Argument für die Funktion. Weitere Details finden Sie hier .
Terdon
1
Noch ein Beispiel mit Spalte:echo -e "\n"{1..100} | column -c40 -x
Jimmyij
@jimmij verdammt! Ich wusste, dass mir einer fehlte! Warum nicht das als Antwort posten?
Terdon
Warum all dies in einer Antwort zusammenfassen?
Sparr
@Sparr warum sollte ich sie aufteilen? Es überfüllt die Website nur mit mehr Antworten als nötig und stinkt nach Repräsentantenhuren.
Terdon
4

Mit 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

(Letzteres funktioniert auch in neueren Versionen von ksh93 oder bash).

Stéphane Chazelas
quelle
2

mit Schleife:

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

Ausgabe:

1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
Hackaholic
quelle
if ! ((x%5)); then echooderif ((x%5 == 0)); then echo
Bis auf weiteres angehalten.
1
Was gibt's Neues?? Hier??
Hackaholic
[ $(($x%5)) -eq 0 ]ist unnötig ausführlich.
Bis auf weiteres angehalten.
1
Es ist nicht unnötig, Sie können dies tun oder auf Ihre Weise tun, es ist einfach anders
Hackaholic
2

Mit awkkann man sagen:

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

Es gibt zurück:

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

Grundsätzlich wird das Trennzeichen für Ausgabedatensätze (Zeilentrennzeichen) entweder durch ein Feldtrennzeichen (Leerzeichen als Standard) oder durch ein Datensatztrennzeichen (neue Zeile als Standard) geändert. Wenn also die Anzahl der Zeilen ein Vielfaches von ist 5, wird eine neue Zeile hinzugefügt. sonst ein Leerzeichen.

Ich habe eine breitere Erklärung in einer ähnlichen Frage geschrieben: bash / sed / awk / etc entferne jede andere neue Zeile .

fedorqui
quelle
1

Sie können verwendet werden seq, trund sed:

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

Oder als optimierte Kombination der Antworten von Olivier, Benoit und mir (in seinen Kommentaren):

seq 15 | xargs -n 5
Anthon
quelle
Sie brauchen nicht tr, verwenden Sie seq -s" " 15stattdessen.
Cuonglm
1

Alle eleganten Lösungen wurden getroffen ... also mit GNU awkundbash

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

oder mit 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
iruvar
quelle