Как сохранить имя файла с косой чертой
Обновлено: 03.07.2024
Я пишу сценарий для резервного копирования. Я составляю список файлов следующим образом:
Переменная LISTOFFILES хранит примерно что-то вроде:
Мой следующий шаг:
Я понимаю, что Баш предполагает, что Python и Tutorial.pdf это разные файлы.
Есть ли способ сделать список файлов с обратной косой чертой, включенный в find или я должен использовать ls с трубами?
Я хочу прочитать ваши советы и рекомендации.
Другой мой вопрос:
Ответ на этот вопрос не очень важен, но один совет может помочь
Как вывести список файлов только с именем файла без пути к файлу?
Например: file вместо /home/user/file .
Я пытаюсь с find команда с prune и path варианты, но мне это не удалось.
Что касается вашего основного вопроса, вам нужно будет использовать другой подход. Ваш метод помещает все файлы в одну строку в $ LISTOFFILES. Затем, когда вы переходите к нему, вы не используете кавычки, которые заставляют его разбиваться на пробелы и давать вам результат, который вы видите.
Самый простой способ получить желаемый результат:
Что мы сделали, так это запустить find и разделить каждый результат символом NULL (часть -print0). Результат find затем передается по конвейеру в xargs, который читает список файлов, разделенных символом NULL (аргумент -0 указывает xargs сделать это), и передает этот список файлов в качестве аргументов в tar.
По вашему второму вопросу: если вы хотите получить только имена файлов только из find команда, используйте printf
Если вы имеете в виду в целом, а не только с помощью find, проще всего использовать basename .
basename предназначено именно для этого и ничего больше.
- 1 . или, если вы не хотите создавать новый процесс с basename вы можете использовать расширение параметра.
- Да, собирался сделать простое более эффективным :-). Есть также проблемы с этой первой командой, например, когда вы получаете большое количество файлов, поскольку вы можете превысить максимальное количество аргументов (в дополнение к созданию дополнительной процедуры для xargs). Можно сделать цикл чтения во время, но гораздо сложнее.
Вы можете собрать список имен файлов, возвращаемых find , но только если в именах файлов нет новых строк, и вам нужно принять меры предосторожности.
Когда вы пишете замену команды или расширение переменной без кавычек, например $LISTOFFILES здесь оболочка выполняет разделение слов и подстановку (подстановочные знаки) в результате.
Правило: всегда заключайте в двойные кавычки замену команд и расширение переменных.
Исключение: если вы понимаете, почему нужно избегать двойных кавычек и почему это безопасно.
Здесь вам нужно опустить двойные кавычки, потому что разделение слов - это то, что разбивает строку на биты, разделенные новой строкой. Но по умолчанию он также разделяется на другие символы пробела. Так что вам нужно сделать это безопасным, а также отключить глобус. Вы достигнете первого, установив IFS переменную в одну новую строку, а последнюю - путем вызова set -f .
Обратите внимание, что обратная косая черта не используется. Обратные косые черты используются, когда вы вводите имена файлов напрямую, а не когда они создаются такими командами, как find .
Обычный способ использования find
Вместо того, чтобы анализировать вывод find , вы должны заставить его вызывать команду, которую вы хотите запустить для файлов, через -exec действие.Это позаботится о случае, когда файлов так много, что превышена максимальная длина командной строки: программа запускается столько раз, сколько необходимо.
Здесь это немного сложно, потому что вы не можете вызывать tar -c несколько раз (при каждом вызове он будет начинаться с нового пустого архива). Но см. Tar up все PDF-файлы в каталоге, сохранив структуру каталогов
Более простые методы
Если файлов не так много, и вы используете ksh93 или bash ≥4 или zsh, используйте ** подстановочный знак для рекурсии в подкаталоги. Сначала вам нужно установить некоторые параметры оболочки:
В zsh без особых настроек вы можете записать этот шаблон как
/**/*.(PDF|pdf|ODT|odt) . После setopt extglob , вы можете написать это как
Или вы можете использовать pax:
Если вам не нужен префикс пути
Есть способы с tar и pax , но самый простой способ - сначала перейти в каталог, который вы хотите заархивировать.
Первый вопрос:
Ответ на ваш первый вопрос: quotes .
Вместо того, чтобы делать -> tar cvf backup.tar $LISTOFFILES
Сделай это -> tar cvf backup.tar '$LISTOFFILES'
Давайте посмотрим на пример (я взял один из ваших файлов для этой демонстрации, даже если файл не существует на моем компьютере, посмотрите на ошибку, которую я получаю с кавычками и без них) -
Ошибка появилась для двух файлов /home/user/Python и Tutorial.pdf . Поставим quote нашим variable и посмотрим, что у нас получится.
Ошибка появилась только один раз для файла /home/user/Python Tutorial.pdf
Второй вопрос:
Подрезать /path/to/file есть несколько способов. Моим любимым было бы awk но я покажу тебе одну для sed тоже.
sed метод:
Вы можете включить это в свой скрипт следующим образом:
Здесь нужно помнить, что мы делаем substitution . Мы заменяем /home/user/ к nothing . Если ты find файлы из более чем одного каталога, то вы можете сделать тонны и тонны замен (yikes!) или сделать awk путь.
awk метод:
Ага, вот и все. Будет работать для файлов, которые вы find в любом каталоге или их подкаталогах.
Итак, ваш сценарий может иметь это следующим образом -
Другие советы и хитрости:
Вот несколько случайных советов, которые, я думаю, могут быть вам полезны -
Чтобы find имена файлов insensitively , используйте iname вместо того, что у вас есть прямо сейчас. Проверь это -
Другие способы обрезки /path/to/file с помощью basename . Я приведу пример, и вы можете включить его в свой сценарий, если вам будет удобно.
Надеюсь это поможет!
- Ваше решение для цитаты не сработает, потому что все файлы будут объединены как один аргумент. Единственный способ сделать это с переменными оболочки - использовать массив, который не может работать (надежно) с первоначально используемым подходом.
- Я попробовал на своем компьютере. Работал нормально. [jaypal:
Читайте также: