Wie vermeide ich das Drucken einer neuen Zeile, wenn die Sequenz abgeschlossen ist?

7

So erstellen Sie eine Spaltenüberschrift wie folgt:

1234567890123456789

Ich (versuche es) benutze seq und echo:

seq -s '' 1 9 ; echo -n 0; seq -s '' 1 9

Seq gibt jedoch nach jedem Lauf eine neue Zeile aus. Wie kann ich das vermeiden?

GreenMatt
quelle
Möchten Sie näher erläutern, warum Sie nicht einfach können echo 1234567890123456789? und warum brauchst du nur 19 spalten? und warum das echo -n 0; seq -s '' 1 9statt seq -s '' 0 9?
Pizdelect
@pizdelect: Q1 & 2: Ich suche nach einer erweiterbaren Methode, die in ein Skript eingefügt werden kann. F3: Weil ich keine führende 0 will.
GreenMatt
Q1 & Q2. Worauf möchten Sie es erweitern? In meiner Antwort erklärte ich, wie man einen Header so breit wie das Terminal macht, ohne die Zahlen byteweise zu schreiben. Und das lässt sich leicht anpassen, z. ein Header wie abcdeabcde.... Q3. Die beiden Befehle aus meinem Kommentar sind gleichwertig.
Pizdelect
Wenn eine der Antworten Ihr Problem gelöst hat, akzeptieren Sie sie bitte , indem Sie auf das Häkchen daneben klicken. Vielen Dank!
Jeff Schaller

Antworten:

10

Angenommen, Sie möchten nur drucken 1234567890123456789, können Sie dies tun mit:

$ printf "%s" $(seq 1 9) $(seq 0 9)
1234567890123456789$

Das wird aber überhaupt keine nachgestellte Newline haben, also bevorzugen Sie vielleicht:

$ printf "%s" $(seq 1 9) $(seq 0 9) $'\n'
1234567890123456789
$

Einige einfachere Möglichkeiten , wenn Sie nicht brauchen , um den Einsatz seq:

$ perl -le 'print 1..9,0,1..9'
1234567890123456789
$ printf "%s" {1..9} {0..9} $'\n'
1234567890123456789

Da Sie Portabilität erwähnt, empfehle ich Ihnen die Verwendung perlAnsatz, oder wenn Sie wahrscheinlich Begegnung Systeme sind ohne perl, und doch müssen den gleichen Befehl in Schalen laufen , einschließlich bash, sh, dash, tcshusw, versuchen Kamils Ansatz .

terdon
quelle
1
@ GreenMatt ah, das kommt darauf an. Für extreme Portabilität können Sie auch nur perldie Shell-Agnostik verwenden. Das printf "%s" $(seq 1 9) $(seq 0 9)funktioniert in jeder POSIX-Shell, einschließlich shund dash, aber das printf "%s" $(seq 1 9) $(seq 0 9) $'\n'schlägt fehl dash. Beachten Sie, dass es funktioniert in sh(oder zumindest in bashläuft wie sh, so in POSIX - Modus), gehe ich davon aus Sie Ubuntu oder ein simmilar System , dessen laufen shtatsächlich ist dash. tcshist seltsam und versucht nicht einmal, POSIX zu sein. Erwarten Sie also nicht, dass einer der Shell-basierten Ansätze dort funktioniert.
Terdon
3
@ GreenMatt Wenn Sie Portabilität benötigen, sollten Sie diese natürlich auch vermeidenecho .
Terdon
2
@ GreenMatt lol. Sagen Sie, was Sie an Perl mögen, Sie können es für die Textmanipulation einfach nicht übertreffen und es ist extrem portabel.
Terdon
1
@ Larry, nicht mit dieser printfStruktur, die Sie nicht können, wird die Formatzeichenfolge für jedes Argument wiederholt, aber wir wollen nur eine neue Zeile.
Ilkkachu
1
@ Larry, mm, der Befehl , den Sie als Kommentar gepostet haben, gibt eine Ziffer pro Zeile aus. Aber ich fange an zu denken, dass Sie das als eigene Antwort posten sollten, wenn Sie es verfeinern oder weiter diskutieren möchten.
Ilkkachu
6

Sie können Zeilenumbrüche aus jedem Stream mit entfernen tr -d '\n'. In Ihrem Fall

(seq -s '' 1 9 ; echo -n 0; seq -s '' 1 9) | tr -d '\n'

Während sich andere Antworten möglicherweise darauf konzentrieren, Ihren ursprünglichen Ansatz zu ändern, sollten auf diese Weise nur Zeilenumbrüche entfernt werden, unabhängig davon, was vorher war |.

Kamil Maciorowski
quelle
1
Nett. Dies hat auch den Vorteil, dass es für die meisten (alle?) Schalen tragbar ist. Ich denke, das OP will die endgültige Newline, also könnte eine andere Option sein ( seq -s '' 1 9 ; echo -n 0 ; seq -s '' 1 9 ) | tr -d '\n' ; printf "\n".
Terdon
Ah ja, ich denke nie daran tr.
GreenMatt
+1. Erwähnenswert ist auch , dass die BSD-Version von vollständiger seqbehandelt wird -s ''als die von GNU - es wird keine neue Zeile gedruckt, selbst wenn sie beendet wird (sie würden dort überhaupt nicht auftreten)
Poige
Meine Meinung
poige
5

Ich gehe davon aus, dass Sie nicht nur diese bestimmte Zeichenfolge möchten, sondern Zeichenfolgen mit inkrementellen Ziffern und variabler Länge. Aus diesem Grund kann es nützlich sein, die Breite durch Ändern einer Nummer ändern zu können, anstatt sie aus mehreren Anrufen an erstellen zu müssen seq.

In Bash könnten Sie so etwas verwenden (für eine 19-lange Sequenz):

for ((i=1; i <= 19; i++)); do printf "%d" "$(( i % 10 ))"; done; echo

Dies sollte in einer Standard-Shell funktionieren (und zumindest in Dash und Busybox):

i=1; while [ "$i" -le 19 ]; do printf "%d" "$(( i % 10 ))"; i=$((i+1)); done; echo
ilkkachu
quelle
+1: Der letztere Ansatz sieht so aus, als ob alles, was er braucht, für mich in jeder POSIX-y-Shell verfügbar sein sollte.
Charles Duffy
4

Beachten Sie auch:

printf '%d' $(seq -w 1 1 99 | cut -c2)

Wir generieren die Zahlen 01..99, null-aufgefüllt ( -w), und entfernen dann die Zehnerstelle . Diese Ein-Platz-Nummern werden dann gesendet, printfum einzeln gedruckt zu werden.

Verwenden Sie 19stattdessen Folgendes, um die gewünschte Ausgabe zu erhalten:

$ printf '%d' $(seq -w 1 1 19 | cut -c2)
1234567890123456789
Jeff Schaller
quelle
1

Verwenden Sie einfach eine Befehlsausführung, um den nachfolgenden Zeilenumbruch zu entfernen:

 $ echo "test$(seq -s '' 9)no-newline"
 test12345679no-newline

Oder erfassen Sie es in einer Variablen:

 $ var=$(seq -s '' 9); echo "${var}0${var}"
 1234567890123456789

Oder auch:

 $ printf '%s' {{0..9},0,{0..9}}; echo
 1234567890123456789
Isaac
quelle
0

Ich frage mich, warum Sie nicht einfach:

echo 1234567890123456789

Und was bringt es, nur 19 statt 20 Spalten zu drucken?

Wenn Sie möchten, dass es wiederholt wird (standardmäßig: für die gesamte Breite des Terminals)

chdr(){ c=${1:-$COLUMNS}; while [ "$c" -gt 0 ]; do printf '%.*s' "$c" 1234567890; c=$((c-10)); done; echo; }
chdr 17
12345678901234567
chdr
12345678901234567890123456789012345678901234567890123456789012345678901234567890

Das wird natürlich nicht funktionieren csh(huh).

Zu Ihrer Information: seqist nicht portabel (es gibt jot* BSD, aber es ist ganz anders).

pizdelect
quelle
0

Wenn Sie verwendentr , um nachgestellte Zeilenumbrüche zu entfernen, sollten Sie sich darüber im Klaren sein, dass alle Vorkommen der in der -dOption angegebenen Zeichen gelöscht werden. So können Sie es etwas schlanker machen:

(seq 1 9; echo 0; seq 1 9) | tr -d '\n'

- echomuss auch nicht -nmehr haben.

Und der Vollständigkeit halber: Die BSD-Version von, seqwenn -s ''angegeben, erzeugt beim Beenden keine neue Zeile.

poige
quelle