Извините, если есть ответ в другом месте, я не знаю, как искать мою проблему.
Я выполнял некоторые симуляции на HPC-сервере Redhat Linux, и мой код для обработки структуры папок с целью сохранения результатов был неудачной. Мой код Matlab для создания папки был:
folder = [sp.saveLocation, 'run_', sp.run_number, '/'];
где sp.run_number
было целое число Я забыл преобразовать его в строку, но по какой-то причине запуск mkdir(folder);
(в Matlab) все же завершился успешно. Фактически, симуляции проходили без сбоев, и данные сохранялись в соответствующем каталоге.
Теперь, когда структура папок запрашивается / печатается, я получаю следующие ситуации:
- Когда я пытаюсь во вкладке автозаполнения:
run_ run_^A/ run_^B/ run_^C/ run_^D/ run_^E/ run_^F/ run_^G/ run_^H/ run_^I/
- Когда я использую
ls
:run_ run_? run_? run_? run_? run_? run_? run_? run_? run_? run_?
. - Когда я перехожу на свой Mac с помощью rsync,
--progress
опция показывает:run_\#003/
и т. Д. С (я полагаю) числом, совпадающим с целым числом,sp.run_number
дополненным до трех цифр, поэтому 10-й прогонrun_\#010/
- Когда я просматриваю папки в Finder, я вижу
run_ run_ run_ run_ run_ run_ run_ run_ run_ run_?
- Глядя на этот вопрос и используя команду,
ls | LC_ALL=C sed -n l
я получаю:
run_$
run_\001$
run_\002$
run_\003$
run_\004$
run_\005$
run_\006$
run_\a$
run_\b$
run_\t$
run_$
Мне не удается cd
войти в папки, используя любое из этих представлений.
У меня есть тысячи этих папок, поэтому мне нужно исправить это с помощью скрипта. Какой из этих параметров является правильным представлением папки? Как программно обратиться к этим папкам, чтобы я переименовал их с правильно отформатированным именем, используя скрипт bash? И я думаю, ради любопытства, как, черт возьми, это произошло в первую очередь?
^A
буквально не^
сопровождаетсяA
, но Ctrl-A (вы можете набрать его, используя Ctrl-V Ctrl-A, так как Ctrl-A обычно является ярлыком для оболочки).run_
мне нужно что-то напечатать/
. Допустим любой другой символ, включая управляющие символы. Я не знаю, что сделал бы matlab, если бы sp.run_number был равен 0 (вероятно, либо прервался с ошибкой, либо произвелrun_
, так как байт NUL завершил бы строку имени каталога). Конечно, это также было бы проблематично для 16-битных (или более высоких) значений, в которых содержался байт NUL, и также варьировалось бы в соответствии с порядком байтов в системе, выполняющей matlab.Ответы:
Вы можете использовать
rename
утилиту perl (akaprename
илиfile-rename
) для переименования каталогов.Примечание: Это не следует путать с
rename
сutil-linux
, или любым другим вариантом.При этом используется
ord()
функция perl для замены каждого управляющего символа в имени файла порядковым номером для этого символа. например,^A
становится 1,^B
становится 2 и т. д.-n
Вариант для сухой трассы , чтобы показать , чтоrename
будет делать , если вы позволите. Удалите его (или замените его-v
для подробного вывода), чтобы фактически переименовать.e
Модификатора вs/LHS/RHS/eg
эксплуатации причин Perl для выполнения RHS (замена) в качестве Perl кода, и$1
это совпавшие данные (контроль символов) от LHS.Если вы хотите, чтобы числа в именах файлов были дополнены нулями, вы можете комбинировать
ord()
сsprintf()
. напримерПриведенные выше примеры работают тогда и только тогда, когда
sp.run_number
в вашем скрипте matlab было значение в диапазоне 0..26 (поэтому он генерирует управляющие символы в именах каталогов).Чтобы иметь дело с ЛЮБЫМ 1-байтовым символом (то есть с 0..255), вы должны использовать:
Если
sp.run_number
бы это могло быть> 255, вам бы пришлось использоватьunpack()
функцию perl вместоord()
. Я не знаю точно, как matlab выводит не преобразованный int в строку, поэтому вам придется экспериментировать. Смотритеperldoc -f unpack
подробности.например, следующее распакует как 8-битные, так и 16-битные значения без знака и дополнит их нулями до 5 цифр:
источник
-n
опцией, но она говорит мне, что это недопустимая опция - информация о версии дает мне,rename from util-linux 2.23.2
поэтому я не уверен, что это та же самая функцияrename
.util-linux
«srename
очень отличается, гораздо менее способны, и параметры командной строки несовместимы. если вы используете Debian или аналогичный, попробуйте установитьfile-rename
пакет. в противном случае установите соответствующий пакет для вашего дистрибутива. он может быть уже установлен, попробуйте запуститьprename
илиfile-rename
вместо простоrename
.Таким образом, может показаться, что
mkdir([...])
в Matlab объединяются члены массива для построения имени файла в виде строки. Но вместо этого вы дали ему число, а цифры - это то, чем на самом деле являются символы на компьютере. Итак, когда этоsp.run_number
было1
, он дал вам символ со значением1
, а затем символ со значением2
и т. Д.Это управляющие символы, они не имеют печатных символов, и печать их на терминале будет иметь другие последствия. Таким образом, вместо этого они часто представлены различными видами экранированных символов :
\001
(восьмеричное),\x01
(шестнадцатеричное),^A
все это общие представления для символа со значением1
. Символ со значением ноль немного отличается, это байт NUL, который используется для обозначения конца строки в C и в системных вызовах Unix.Если вы поднялись выше 31, вы начнете видеть печатные символы, 32 - это пробел (хотя и не очень заметный), 33 =
!
, 34 ="
и т. Д.Так,
run_ run_^A/ run_^B/
- Первыйrun_
соответствует тому, с нулевым байтом, строка заканчивается там. Другие показывают, что вашей оболочке нравится использовать отображение контрольных кодов с помощью^A
. Запись также намекает на тот факт, что символ с числовым значением 1 может быть введен как Ctrl-A, хотя вы должны указать оболочке интерпретировать не как управляющий символ, а как литерал, это Ctrl-V Ctrl-Aдолжно быть сделано по крайней мере в Bash.ls:
run_ run_? run_?
-ls
не любит печатать непечатаемые символы на терминале, он заменяет их на вопросительные знаки.rsync:
run_\#003/
- это что-то новое для меня, но идея та же, обратная косая черта означает побег, а остальное - числовое значение персонажа. Мне кажется, что число здесь восьмерично, как и в более общем\003
.с помощью команды
ls | LC_ALL=C sed -n l
...run_\006$
run_\a$
run_\b$
run_\t$
-\a
,\b
и\t
C выходы для тревоги (звонок), Backspace и Tab, соответственно. Они имеют числовые значения 7, 8 и 9, поэтому должно быть понятно, почему они идут после\006
. Использование этих escape-символов C - это еще один способ пометить управляющие символы. Конечные знаки доллара отмечают конец линии.Что касается
cd
, если предположить, что мои предположения верны,cd run_
следует перейти к этому единственному каталогу без нечетного завершающего символа иcd run_?
выдать ошибку, поскольку вопросительный знак является символом глобуса, который соответствует любому отдельному символу, и существует несколько совпадающих имен файлов, ноcd
только ожидает одного.Все они, в некотором смысле ...
В Bash вы можете использовать
\000
и\x00
экранирование внутри$'...'
кавычек для представления специальных символов, поэтому$'run_\033
(восьмеричное) или$'run_\x1b'
соответствовать каталогу со значением символа 27 (которое, как оказалось, является ESC). (Я не думаю, что Bash поддерживает экранирование с десятичными числами.)В ответе cas есть сценарий для их переименования, поэтому я не пойду туда.
источник
ls
, есть несколько параметров цитирования, включая-b
/--escape
и--quoting-style=
, илиQUOTING_STYLE
переменную окружения, для управления отображением непечатаемых символов. Я не думаю, что есть возможность сделать так, чтобы он предпочитал восьмеричные экранирования над версиями персонажей.Проще всего было бы создать неправильное имя файла и правильное имя файла в той же среде, где произошла ошибка, а затем просто переместить / переименовать папки с правильными именами.
Чтобы избежать коллизий между существующими именами, лучше использовать другую папку назначения.
Если возможно, я бы предпочел исправить скрипт и просто запустить его снова; исправление какой-то странной ошибки после смерти, вероятно, стоит дороже и может привести к новым проблемам.
Удачи!
источник