Wichtig ist, dass :>es sich nicht um einen einzelnen Bediener handelt. Es ist möglicherweise einfacher zu verstehen, wenn Sie es : > filestattdessen als lesen .
jpfx1342
Es bedeutet , dass die Person , die das Skript zu schreiben , sollte die Ausgabe der Schleife in die Datei umgeleitet hat: while read A B C D E; do echo "$A;$B;$D;$E;$C"; done < otherfile > file. Oder noch besser, sie hätten das richtige Werkzeug für den Job verwenden sollen, awk, wie von Peter vorgeschlagen . Abgesehen davon möchten Sie den -rSchalter fast immer mit verwendenread .
Tom Fenech
Außerhalb der Bash wäre es ein Smiley für eine Krähe.
smci
Antworten:
46
Es gab:> in einer Zeile eines Bash-Skripts. Was heißt das?
:> file
Es ist eine Abkürzung, um zu sagen:
Wenn filees nicht existiert, dann erstelle es, andernfalls schneide es auf 0Bytes ab.
Das bedeutet, Sie können sicher sein, dass es fileexistiert und es leer ist.
Sie können auch verwenden > file, :> fileist aber tragbarer.
Ich verstehe die zweite Zeile nicht. Ich dachte, dass read Variablen liest. Befehlsecho ist auch seltsam. Könntest du erklären?
diego9403
Ich bin kein Unix-Experte, aber ich denke, die zweite Zeile liest Dinge aus otherfileund gibt echosie aus file. Es macht auch Variablen aus dem, was es liest ... Wenn Sie eine eindeutige Antwort wünschen, stellen Sie bitte Ihre eigene Frage.
DavidPostill
2
@ diego9403: Ruft eine readEingabe von stdin ab. Allein würde es lesen, was Sie eingeben. Da stdin weitergeleitet wurde, <otherfilewird der Inhalt von otherfilein stdin "getippt". So werden readdie Werte zeilenweise in die Variablen $ A, $ B, $ C, $ D und $ E geschrieben.
Slebetman
Es ist also nur eine obskurere Alternative zu truncateCoreutils?
Federico Poloni
1
@PeterCordes Ich meinte nicht "obskur" wie in "es ist ungewöhnlich", aber wie in "es ist weniger klar für den Leser".
Federico Poloni
29
Es sieht aus wie eine ausgefallene Art, eine neue Datei zu erstellen. In bash:ist ein Null-Befehl:
$ type :: is a shell builtin
$ help ::::Null command.No effect; the command does nothing.ExitStatus:Always succeeds.
Die Datei wird auch abgeschnitten, wenn sie bereits vorhanden ist ...
DavidPostill
2
ja, das ist , was >tut
Arkadiusz Drabczyk
2
:ist eine Abkürzung für true. Möglicherweise in einigen Muscheln, trueist ein eingebautes nicht? Beide sind in bash integriert.
Peter Cordes
12
:ist ein anderer Name für true. Beide sind Shell-Builtins in Bash, aber es gibt keine /bin/:, nur eine /bin/true. Die Ausgabeumleitung bewirkt, dass die Shell open(2)die Datei mit O_CREAT|O_TRUNC. Wenn nichts geschrieben ist, bleibt die Länge Null.
Das Zusammenfügen dieser beiden Teile :> fileist eine gängige Redewendung für das Abschneiden von Dateien. Die meisten Leute würden versuchen, es durch Schreiben weniger komisch aussehen zu lassen : >file.
Da Sie in einem Kommentar zur 2. Zeile gefragt haben, werde ich meine Kommentare in eine Antwort umwandeln. (Auch wenn Sie dies nicht in Ihrer Frage gestellt haben.)
Die 2. Zeile ist eine Schleife, die Zeilen otherfilein einige benannte Variablen einliest . Der Schleifenkörper echodruckt sie mit ;Trennzeichen anstelle der zuvor verwendeten Leerzeichen. filewird bei jeder Iteration geschlossen und erneut geöffnet (zum Anhängen), da sich die Umleitung innerhalb der Schleife befindet. Die Verwendung von while ...;do read -r ...;done <otherfile >filewürde weniger lästig sein, und Sie müssen die Datei nicht erst abschneiden. read -risst nicht \als Fluchtcharakter.
Die Textverarbeitung in Bash ist ziemlich langsam. Ein Teil davon ist unvermeidlich: Es readmuss jeweils ein Byte (ein read(2)Systemaufruf pro Byte) gesendet werden, um ein Überschießen des Zeilenendes zu vermeiden. Es wäre besser, das richtige Werkzeug für den Job zu verwenden:
--bedeutet, dass Ihr Skript nicht kaputt geht, wenn der otherfileName "albern" lautet --version.
Wenn Sie das Ausgabefeldtrennzeichen auf festlegen, ;können Sie nur mehrere Felder als Argumente zum Drucken übergeben. Shell readweist der letzten Variablen den gesamten Rest der Zeile mit Leerzeichen zu, aber es gibt keine Möglichkeit, awk anzuweisen, nur in 5 aufzuteilen. Perl macht dies einfach, da splites ein Maximum an Feldern haben kann, aber es ist viel langsamer zu starten als awk.
Eigentlich stellte sich heraus, dass es nicht so schwer war, nur einen hässlichen Regex zu schreiben. $5Wenn Sie nicht in awk, sondern in Rest-of-the-Line arbeiten möchten, verlieren Sie beim Überlaufen von Feldern immer noch das ursprüngliche Leerzeichen. Meine erste tragfähige Idee ist , zu verwenden , gensubauf $0(die ganze Zeile) die ersten 4 Felder (dh nicht-Raum , gefolgt von Raum) zu entfernen, so dass alles anderes:
Ich habe es gleich beim ersten Versuch richtig verstanden, aber die Tatsache, dass ich davon beeindruckt war, sagt etwas über die Lesbarkeit dieses awk-Codes aus. >. <
Beachten Sie, wie es das gleiche ist printwie zuvor, aber mit tailanstelle von $5.
echo 'A B c DD e f g f'|
awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
print $1, $2, $4, tail, $3 }'
A;B;DD;e f g f;c
Dies wäre beeindruckender, wenn ich das Literal kopieren / einfügen und zeigen könnte, dass es in der Ausgabe durchgekommen ist. Tippe eins in bash mit ^ Q. ctrl-Q bedeutet Zitieren Sie den nächsten Tastendruck als wörtliches Zeichen, da die Zeilenbearbeitung im Emacs-Stil von bash mit der von Emacs identisch ist.
http://mywiki.wooledge.org/BashFAQ enthält einige nützliche Informationen zum Thema Skripterstellung, die unabhängig davon, welche Daten oder Dateinamen Sie in das Skript einfügen, keine Probleme verursachen.
:>
es sich nicht um einen einzelnen Bediener handelt. Es ist möglicherweise einfacher zu verstehen, wenn Sie es: > file
stattdessen als lesen .while read A B C D E; do echo "$A;$B;$D;$E;$C"; done < otherfile > file
. Oder noch besser, sie hätten das richtige Werkzeug für den Job verwenden sollen, awk, wie von Peter vorgeschlagen . Abgesehen davon möchten Sie den-r
Schalter fast immer mit verwendenread
.Antworten:
Es gab:> in einer Zeile eines Bash-Skripts. Was heißt das?
Es ist eine Abkürzung, um zu sagen:
file
es nicht existiert, dann erstelle es, andernfalls schneide es auf0
Bytes ab.Das bedeutet, Sie können sicher sein, dass es
file
existiert und es leer ist.Sie können auch verwenden
> file
,:> file
ist aber tragbarer.Siehe die Stapelüberlauf-Frage Was ist der Zweck des ':' (Doppelpunkt) GNU Bash Builtin? für mehr Informationen.
quelle
otherfile
und gibtecho
sie ausfile
. Es macht auch Variablen aus dem, was es liest ... Wenn Sie eine eindeutige Antwort wünschen, stellen Sie bitte Ihre eigene Frage.read
Eingabe von stdin ab. Allein würde es lesen, was Sie eingeben. Da stdin weitergeleitet wurde,<otherfile
wird der Inhalt vonotherfile
in stdin "getippt". So werdenread
die Werte zeilenweise in die Variablen $ A, $ B, $ C, $ D und $ E geschrieben.truncate
Coreutils?Es sieht aus wie eine ausgefallene Art, eine neue Datei zu erstellen. In
bash
:
ist ein Null-Befehl:>
Leitet die Ausgabe:
in eine Datei um.quelle
>
tut:
ist eine Abkürzung fürtrue
. Möglicherweise in einigen Muscheln,true
ist ein eingebautes nicht? Beide sind in bash integriert.:
ist ein anderer Name fürtrue
. Beide sind Shell-Builtins in Bash, aber es gibt keine/bin/:
, nur eine/bin/true
. Die Ausgabeumleitung bewirkt, dass die Shellopen(2)
die Datei mitO_CREAT|O_TRUNC
. Wenn nichts geschrieben ist, bleibt die Länge Null.Das Zusammenfügen dieser beiden Teile
:> file
ist eine gängige Redewendung für das Abschneiden von Dateien. Die meisten Leute würden versuchen, es durch Schreiben weniger komisch aussehen zu lassen: >file
.Da Sie in einem Kommentar zur 2. Zeile gefragt haben, werde ich meine Kommentare in eine Antwort umwandeln. (Auch wenn Sie dies nicht in Ihrer Frage gestellt haben.)
Die 2. Zeile ist eine Schleife, die Zeilen
otherfile
in einige benannte Variablen einliest . Der Schleifenkörperecho
druckt sie mit;
Trennzeichen anstelle der zuvor verwendeten Leerzeichen.file
wird bei jeder Iteration geschlossen und erneut geöffnet (zum Anhängen), da sich die Umleitung innerhalb der Schleife befindet. Die Verwendung vonwhile ...;do read -r ...;done <otherfile >file
würde weniger lästig sein, und Sie müssen die Datei nicht erst abschneiden.read -r
isst nicht\
als Fluchtcharakter.Die Textverarbeitung in Bash ist ziemlich langsam. Ein Teil davon ist unvermeidlich: Es
read
muss jeweils ein Byte (einread(2)
Systemaufruf pro Byte) gesendet werden, um ein Überschießen des Zeilenendes zu vermeiden. Es wäre besser, das richtige Werkzeug für den Job zu verwenden:--
bedeutet, dass Ihr Skript nicht kaputt geht, wenn derotherfile
Name "albern" lautet--version
.Wenn Sie das Ausgabefeldtrennzeichen auf festlegen,
;
können Sie nur mehrere Felder als Argumente zum Drucken übergeben. Shellread
weist der letzten Variablen den gesamten Rest der Zeile mit Leerzeichen zu, aber es gibt keine Möglichkeit, awk anzuweisen, nur in 5 aufzuteilen. Perl macht dies einfach, dasplit
es ein Maximum an Feldern haben kann, aber es ist viel langsamer zu starten als awk.Eigentlich stellte sich heraus, dass es nicht so schwer war, nur einen hässlichen Regex zu schreiben.
$5
Wenn Sie nicht in awk, sondern in Rest-of-the-Line arbeiten möchten, verlieren Sie beim Überlaufen von Feldern immer noch das ursprüngliche Leerzeichen. Meine erste tragfähige Idee ist , zu verwenden ,gensub
auf$0
(die ganze Zeile) die ersten 4 Felder (dh nicht-Raum , gefolgt von Raum) zu entfernen, so dass alles anderes:Ich habe es gleich beim ersten Versuch richtig verstanden, aber die Tatsache, dass ich davon beeindruckt war, sagt etwas über die Lesbarkeit dieses awk-Codes aus. >. <
Beachten Sie, wie es das gleiche ist
print
wie zuvor, aber mittail
anstelle von$5
.Dies wäre beeindruckender, wenn ich das Literal kopieren / einfügen und zeigen könnte, dass es in der Ausgabe durchgekommen ist. Tippe eins in bash mit ^ Q. ctrl-Q bedeutet Zitieren Sie den nächsten Tastendruck als wörtliches Zeichen, da die Zeilenbearbeitung im Emacs-Stil von bash mit der von Emacs identisch ist.
http://mywiki.wooledge.org/BashFAQ enthält einige nützliche Informationen zum Thema Skripterstellung, die unabhängig davon, welche Daten oder Dateinamen Sie in das Skript einfügen, keine Probleme verursachen.
quelle