Das ist eine ernste Frage. Ich awk
teste einige Skripte und benötige Dateien mit einem Zeilenumbruch im Namen.
Ist es möglich, mit einem Dateinamen eine neue Zeile hinzuzufügen mv
?
Ich jetzt kann ich das tun mit touch
:
touch "foo
bar"
Mit Berührung habe ich das Zeilenumbruchzeichen pro Kopieren und Einfügen hinzugefügt. Aber ich kann nicht foo
Returnbar
in meine Shell schreiben .
Wie kann ich eine Datei umbenennen, um eine neue Zeile im Dateinamen zu haben?
Bearbeiten 28.06.2015; 19:08 Uhr
Um eine neue Zeile hinzuzufügen, zsh
kann ich Alt+ verwendenReturn
mv
anders wäre, es zu tun, als es zu tuntouch
? Hast du das Gleiche versucht?mv
genauso einfach kopieren und in den Befehl einfügen wietouch
.Antworten:
Es ist eine schlechte Idee (seltsame Zeichen in Dateinamen zu haben), aber Sie könnten es tun
(Sie hätten es auch tun können
mv somefile.txt "$(printf "foo\nbar")"
odermv somefile.txt foo$'\n'bar
usw. Details sind spezifisch für Ihre Shell. Ich verwendezsh
)Lesen Sie mehr über Globbing , zB Glob (7) . Details können Shell-spezifisch sein. Verstehen Sie jedoch, dass
/bin/mv
(von Ihrer Shell) über execve (2) ein erweitertes Array von Argumenten angegeben wird: Die Erweiterung und das Globbing von Argumenten liegen in der Verantwortung der aufrufenden Shell.Und Sie könnten sogar ein winziges C-Programm codieren, um dasselbe zu tun:
Speichern Sie das obige Programm in
foo.c
, kompilieren Sie es mitgcc -Wall foo.c -o foo
und führen Sie es aus./foo
Ebenso können Sie ein ähnliches Skript in Perl, Ruby, Python, Ocaml usw. codieren.
Das ist aber eine schlechte Idee. Vermeiden Sie Zeilenumbrüche in Dateinamen (dies verwirrt den Benutzer und kann viele Skripte beschädigen ).
Eigentlich empfehle ich sogar, in Dateipfaden nur nicht akzentuierte Buchstaben, Ziffern und
+-/._%
Zeichen (mit/
dem Verzeichnis-Trennzeichen) zu verwenden. "Versteckte" Dateien (beginnend mit.
) sollten mit Vorsicht und Sparsamkeit verwendet werden. Ich glaube, dass die Verwendung von Leerzeichen in einem Dateinamen ein Fehler ist. Verwenden Sie stattdessen einen Unterstrich (zBfoo/bar_bee1.txt
) oder ein Minus (zBfoo/bar-bee1.txt
)quelle
foo
.@
und,
wäre harmloser als-
(wie in der ersten Position) oder%
. Alle diese Empfehlungen dienen hauptsächlich dazu, Fehler in einigen Anwendungen zu umgehen (die bei Dateinamen auftreten, die ansonsten aus Sicht des Betriebssystems gültig sind). Es fühlt sich rückständig an, die Leute zu bitten, diese Zeichen nicht zu verwenden, anstatt ihre Fehler zu beheben.Wenn Sie bash verwenden, sollte dieser Befehl funktionieren.
quelle
zsh
=)Ich weiß, dass Sie nach einer
mv
Lösung gefragt haben , aber trotz der Warnung ist dies leicht möglichrename
(im Perl-Paket):quelle
rename
sehr gute Idee. +1Ein Aspekt dieses Problems betrifft nicht wirklich
awk
- und nur ein wenig die Shell. Das Problem ist, dass auf einem standardmäßigen, kanonischen tty die meiste Zeit die tty-Disziplin des Kernels Ihre Eingaben puffert - sie wird nur auf Ihrem Bildschirm und nirgendwo anders wiedergegeben -, damit sie effizient mit Rückständen und Ähnlichem umgehen können.Wenn Sie jedoch die Eingabetaste drücken oder auf andere Weise eine neue Zeile eingeben, werden alle diese gepufferten Daten auf einmal an die Leseanwendung gesendet - normalerweise an Ihre Shell. Sie können dies beobachten, indem Sie
$PS2
nach Eingabe eines baumelnden Zitats darauf achten. Wenn die Shell gedruckt wird, liegt dies$PS2
daran, dass sie nur einen Block Ihrer Eingabe liest und noch nicht davon überzeugt ist, dass Sie fertig sind.Der
\n
Einfachheit halber benötigen Sie also eine Möglichkeit, eine Ewline in den Terminalpuffer zu senden, ohne die gesamte andere Eingabe sofort verschieben zu müssen. Der üblicher Weg , dies zu tun ist , w / die SchlüsselsequenzCTRL+V
- das Anführungszeichen für das Terminal Ihrer nächsten Eingabezeichen. Tun Sie esCTRL+V
dannCTRL+J
- denn letzteres ist normalerweise das\n
Eingeben einer wörtlichen Ewline. Sie werden wissen, dass es funktioniert, wenn Sie es nicht sehen,$PS2
weil die Shell Ihre Eingabe immer noch nicht gelesen hat.Beachten Sie aber , dass , wenn es nicht gelesen , dass die Eingabe Ihrer früheren
CTRL+V
überhaupt keinen Unterschied für die Schale gemacht haben - , dass zitiert es nur für die Linie Disziplin. Sie sollten auf jeden Fall auch die Newline zitieren, um etwas Sinnvolles daraus zu machen.Übrigens,
CTRL+V
kann auf andere Weise sinnvoll angewendet werden - zum Beispiel"$(printf \\33)"
ist dies nicht die einzige Möglichkeit, einESC
Zeichen in ein Shell-Skript zu schreiben - und es ist nicht einmal die einfachste. Sie können buchstäblich jedes Zeichen eingeben, das Ihre Tastatur sendet, ohne dass der Eingabetreiber versucht, es zu interpretieren, wenn Sie es zuerst auf diese Weise verlassen.Ich verwende oft gerne <tab> s in der Befehlszeile, ohne dass die Shell versucht, etwas zu vervollständigen. Da Shells, die eine Vervollständigung ausführen, <tab> normalerweise so konfigurieren
stty eol \t
, dass ihre VervollständigungssystemeCTRL+V
auch in unbekannten Umgebungen funktionieren, funktioniert dies für mich.quelle