Entschuldigung, wenn dies anderswo eine Antwort hat, ich habe keine Ahnung, wie ich nach meinem Problem suchen soll.
Ich habe einige Simulationen auf einem Red Hat Linux HPC-Server ausgeführt, und mein Code für die Verwaltung der Ordnerstruktur zum Speichern der Ausgabe wies einen unglücklichen Fehler auf. Mein Matlab-Code zum Erstellen des Ordners war:
folder = [sp.saveLocation, 'run_', sp.run_number, '/'];
wo sp.run_number
war eine ganze Zahl. Ich habe vergessen, es in eine Zeichenfolge umzuwandeln, aber aus irgendeinem Grund läuftmkdir(folder);
(in Matlab) immer noch erfolgreich. Tatsächlich liefen die Simulationen reibungslos und die Daten wurden im entsprechenden Verzeichnis gespeichert.
Jetzt, wenn die Ordnerstruktur abgefragt / gedruckt wird, erhalte ich die folgenden Situationen:
- Wenn ich versuche, automatisch zu vervollständigen:
run_ run_^A/ run_^B/ run_^C/ run_^D/ run_^E/ run_^F/ run_^G/ run_^H/ run_^I/
- Wenn ich benutze
ls
:run_ run_? run_? run_? run_? run_? run_? run_? run_? run_? run_?
. - Wenn ich mit rsync auf meinen Mac übertrage,
--progress
zeigt die Option:run_\#003/
etc. mit (ich nehme an) der Zahl, die mit der Ganzzahl in übereinstimmtsp.run_number
drei Ziffern aufgefüllt , also ist der 10. Laufrun_\#010/
- Wenn ich die Ordner im Finder ansehe, sehe ich
run_ run_ run_ run_ run_ run_ run_ run_ run_ run_?
- Wenn ich diese Frage betrachte und den Befehl verwende,
ls | LC_ALL=C sed -n l
bekomme ich:
run_$
run_\001$
run_\002$
run_\003$
run_\004$
run_\005$
run_\006$
run_\a$
run_\b$
run_\t$
run_$
Ich kann cd
mit keiner dieser Darstellungen in die Ordner gelangen.
Ich habe Tausende dieser Ordner, daher muss ich dies mit einem Skript beheben. Welche dieser Optionen ist die richtige Darstellung des Ordners? Wie kann ich programmgesteuert auf diese Ordner verweisen, um sie mithilfe eines Bash-Skripts mit einem ordnungsgemäß formatierten Namen umzubenennen? Und ich schätze aus Neugier, wie zum Teufel ist das überhaupt passiert?
quelle
^A
wird nicht wörtlich^
gefolgtA
, sondern Strg-A (Sie können es mit Strg-V Strg-A eingeben, da Strg-A im Allgemeinen eine Abkürzung für die Shell ist).run_
und ich muss etwas eingeben/
. Jedes andere Zeichen ist gültig, einschließlich Steuerzeichen. Ich weiß nicht, was matlab getan hätte, wenn sp.run_number 0 gewesen wäre (wahrscheinlich entweder mit einem Fehlerrun_
abgebrochen oder erzeugt , da das NUL-Byte den Verzeichnisnamen-String beenden würde). Dies wäre natürlich auch problematisch für 16-Bit-Werte (oder höher), die ein NUL-Byte enthalten, und würde sich auch nach dem Endian des Systems richten, auf dem matlab ausgeführt wird.Antworten:
Sie können das Perl-
rename
Dienstprogramm (auch bekannt alsprename
oderfile-rename
) verwenden, um die Verzeichnisse umzubenennen.HINWEIS: Dies ist nicht zu verwechseln mit
rename
ausutil-linux
, oder jeder anderen Version.Hierbei wird die Perl-
ord()
Funktion verwendet, um jedes Steuerzeichen im Dateinamen durch die Ordnungszahl für dieses Zeichen zu ersetzen. zB^A
wird 1,^B
wird 2, etc.Die
-n
Option ist ein Probelauf, um zu zeigen, was passierenrename
würde , wenn Sie es zulassen. Entfernen Sie es (oder ersetzen Sie es durch-v
eine ausführliche Ausgabe), um es tatsächlich umzubenennen.Der
e
Modifikator in ders/LHS/RHS/eg
Operation veranlasst Perl, die RHS (die Ersetzung) als Perl-Code auszuführen, und das$1
sind die übereinstimmenden Daten (das Steuerzeichen) aus der LHS.Wenn Sie in den Dateinamen
ord()
mit Nullen aufgefüllte Zahlen verwenden möchten, können Sie diese mit kombinierensprintf()
. z.BDie obigen Beispiele funktionieren genau dann, wenn
sp.run_number
in Ihrem Matlab-Skript ein Wert im Bereich von 0..26 angegeben wurde (sodass Steuerzeichen in den Verzeichnisnamen erzeugt wurden).Um mit JEDEM 1-Byte-Zeichen (dh ab 0..255) umzugehen, würden Sie Folgendes verwenden:
Wenn
sp.run_number
> 255 sein könnte, müssten Sieunpack()
stattdessen die Perl- Funktion verwendenord()
. Ich weiß nicht genau, wie matlab ein nicht konvertiertes int in einer Zeichenfolge ausgibt. Sie müssen also experimentieren. Sieheperldoc -f unpack
für weitere Einzelheiten.Das folgende Beispiel entpackt vorzeichenlose 8-Bit- und 16-Bit-Werte und füllt sie mit Nullen auf eine Breite von 5 Stellen auf:
quelle
-n
Option zu testen , aber es sagt mir, dass es eine ungültige Option ist - die Versionsinformationen geben mirrename from util-linux 2.23.2
also nicht sicher, ob es die gleiche Funktion istrename
Dienstprogramms angegeben.util-linux
‚srename
ist ganz anders, viel weniger in der Lage, und die Befehlszeilenoptionen sind nicht kompatibel. Wenn Sie Debian oder ähnliches ausführen, versuchen Sie, dasfile-rename
Paket zu installieren . Installieren Sie andernfalls das entsprechende Paket für Ihre Distribution. Möglicherweise ist es bereits installiert. Versuchen Sie es mit "Ausführen"prename
oderfile-rename
statt "Nur"rename
.Es scheint also, dass
mkdir([...])
in Matlab die Mitglieder des Arrays verkettet werden, um den Dateinamen als Zeichenfolge zu erstellen. Aber Sie haben ihm stattdessen eine Nummer gegeben, und Zahlen sind das, was die Zeichen auf einem Computer wirklich sind. Also, wannsp.run_number
war1
, gab es Ihnen das Zeichen mit Wert1
, und dann das Zeichen mit Wert2
usw.Dies sind Steuerzeichen, sie haben keine druckbaren Symbole, und das Drucken auf einem Terminal hätte andere Konsequenzen. Stattdessen werden sie häufig durch verschiedene Arten von Escapezeichen dargestellt:
\001
(oktal),\x01
(hex)^A
sind alle gebräuchlichen Darstellungen für das Zeichen mit Wert1
. Das Zeichen mit dem Wert Null ist ein bisschen anders, es ist das NUL-Byte, mit dem das Ende einer Zeichenfolge in C und in den Unix-Systemaufrufen markiert wird.Wenn Sie höher als 31 sind, werden druckbare Zeichen angezeigt, 32 ist ein Leerzeichen (allerdings nicht sehr gut sichtbar), 33 =
!
, 34 ="
usw.So,
run_ run_^A/ run_^B/
- Der ersterun_
entspricht dem mit einem Null-Byte, der String endet dort. Die anderen zeigen, dass Ihre Shell die Steuercodes gerne mit anzeigt^A
. Die Notation weist auch darauf hin, dass das Zeichen mit dem numerischen Wert 1 als eingegeben werden kann Ctrl-A, obwohl Sie der Shell mitteilen müssen, dass sie nicht als Steuerzeichen, sondern als Literal interpretieren Ctrl-V Ctrl-Asoll, zumindest in Bash.ls:
run_ run_? run_?
-ls
druckt keine nicht druckbaren Zeichen auf dem Terminal aus, sondern ersetzt sie durch Fragezeichen.rsync:
run_\#003/
- das ist neu für mich, aber die Idee ist dieselbe, der Backslash markiert eine Flucht, und der Rest ist der numerische Wert des Zeichens. Es scheint mir, dass die Zahl hier im Oktal ist, wie in der allgemeineren\003
.mit dem Befehl
ls | LC_ALL=C sed -n l
...run_\006$
run_\a$
run_\b$
run_\t$
-\a
,\b
und\t
sind entzieht C für Alarm (Glocke), Rücktaste und Reiter, respectively. Sie haben die numerischen Werte 7, 8 und 9, daher sollte klar sein, warum sie nachher kommen\006
. Die Verwendung dieser C-Escape-Zeichen ist eine weitere Möglichkeit, die Steuerzeichen zu markieren. Die nachgestellten Dollarzeichen markieren die Zeilenenden.Was
cd
unter der Annahme , meine Annahmen recht,cd run_
in dieser ein einzigen Verzeichnis ohne einen ungeradeen hinteren Charakter gehen sollte, undcd run_?
soll einen Fehler geben , da das Fragezeichen ein glob Zeichen , das für ein einzelnes Zeichen übereinstimmt, und es gibt mehr passenden Dateinamen, sonderncd
nur erwartet einen.In gewisser Weise alle ...
In Bash können Sie das
\000
und\x00
in$'...'
Anführungszeichen setzen, um die Sonderzeichen darzustellen, also$'run_\033
(oktal) oder$'run_\x1b'
dem Verzeichnis mit dem Zeichenwert 27 (zufällig ESC) entsprechen. (Ich glaube nicht, dass Bash Escape-Zeichen mit Dezimalzahlen unterstützt.)cas Antwort hat ein Skript, um diese umzubenennen, also werde ich nicht dorthin gehen.
quelle
ls
, gibt es einige Anführungszeichenoptionen, einschließlich-b
/--escape
und--quoting-style=
oder derQUOTING_STYLE
Umgebungsvariablen, um zu steuern, wie nicht druckbare Zeichen angezeigt werden. Ich glaube nicht, dass es eine Option gibt, die Oktal-Flucht gegenüber den Charakterversionen bevorzugt.Am einfachsten wäre es, den falschen und den richtigen Dateinamen in derselben Umgebung zu erstellen, in der das Missgeschick passiert ist, und dann die Ordner einfach zu den richtigen Namen zu verschieben / umzubenennen.
Verwenden Sie einen anderen Zielordner, um Kollisionen zwischen vorhandenen Namen zu vermeiden.
Wenn möglich, würde ich es vorziehen, das Skript zu reparieren und es erneut auszuführen. Das Reparieren von seltsamen Bugs kostet wahrscheinlich mehr und kann neue Probleme verursachen.
Viel Glück!
quelle