Bash экранирует пробелы в имени файла, в переменной

Я новичок в Bash, так что это может быть что-то тривиальное, но я просто не понимаю. Я пытаюсь избежать пробелов внутри имен файлов. Взглянуть. Обратите внимание, что это «рабочий пример» — я понимаю, что чередование файлов с пустыми страницами может быть выполнено проще, но я здесь о пространстве.

#! /bin/sh

first=true
i=combined.pdf
o=combined2.pdf
for f in test/*.pdf
do
    if $first; then
        first=false
        ifile=\"$f\"
    else
        ifile=$i\ \"$f\"
    fi
    pdftk $ifile blank.pdf cat output $o
    t=$i
    i=$o
    o=$t
    break
done

Скажем, у меня есть файл с именем my file.pdf (с пробелом). Я хочу, чтобы переменная ifile содержала строку combined.pdf "my file.pdf", чтобы pdftk мог использовать ее как два файловых аргумента — первый из них — combined.pdf, а второй — my file.pdf.

Я пробовал различные способы экранирования (с или без предварительного экранирования самих кавычек и т. д.), но он продолжает разбивать my и file.pdf при выполнении pdftk.

РЕДАКТИРОВАТЬ: Чтобы уточнить: я пытаюсь передать несколько имен файлов (как несколько аргументов) в одной переменной команде pdftk. Я хотел бы, чтобы он распознавал разницу между двумя именами файлов, но не разрывал одно имя файла на пробелы.


person Joost    schedule 01.10.2013    source источник
comment
Не для того, чтобы раздражать, но две секунды гугления, и я нашел это: lornajane.net/posts/2011/combining-pdf-files-with-pdftk   -  person Adam Gent    schedule 01.10.2013
comment
Однако это «минимальный рабочий пример» моей проблемы. Я делаю несколько других вещей, прежде чем добавлять файлы.   -  person Joost    schedule 01.10.2013
comment
Ну, потому что вам нужна пустая страница между каждой страницей. Я этого не видел.   -  person Adam Gent    schedule 01.10.2013
comment
Почему ты так усложняешь? Используйте 2 переменные: pdftk "$i" "$f" ...   -  person glenn jackman    schedule 01.10.2013
comment
@AdamGent - спасибо за указатель на lornajane.net/posts/2011/combining-pdf-files-with-pdftk - я узнал кое-что новое с опцией -J для xargs   -  person jaygooby    schedule 13.11.2014


Ответы (2)


Помещение нескольких аргументов в одну переменную не имеет смысла. Вместо этого поместите их в массив:

args=(combined.pdf "my file.pdf");

Обратите внимание, что "my file.pdf" заключено в кавычки для сохранения пробелов.

Вы можете использовать массив следующим образом:

pdftk "${args[@]}" ...

Это передаст два отдельных аргумента в pdftk. Кавычки в "${args[@]}" необходимы, потому что они говорят оболочке рассматривать каждый элемент массива как отдельное «слово» (т. е. не разделять элементы массива, даже если они содержат пробелы).

В качестве примечания: если вы используете bashisms, такие как массивы, измените свой shebang на

#!/bin/bash
person ThisSuitIsBlackNot    schedule 01.10.2013
comment
Я почти уверен, что это не будет работать правильно, если в файле есть пробелы. Я помню, что когда-то у меня были проблемы с выполнением чего-то подобного. - person Adam Gent; 01.10.2013
comment
Это то, что я должен был начать делать с самого начала. Бессмысленно пытаться использовать для этого строку. Спасибо! - person Joost; 01.10.2013
comment
@AdamGent Из раздела bash справочной страницы, посвященного массивам: If the word is double-quoted,...${name[@]} expands each element of name to a separate word. Другими словами, элементы массива не разбиваются на пробелы. - person ThisSuitIsBlackNot; 01.10.2013
comment
@ThisSuitIsBlackNot Я не помню точную проблему, но я думаю, что это была проблема с символом новой строки в имени файла. Мне пришлось использовать нулевой разделитель в стиле find/xargs. - person Adam Gent; 01.10.2013
comment
Проблема xargs синтаксического анализа вывода из find отличается от проблемы с цитированием пробелов, чтобы оболочка не выполняла разделение слов на нем. - person chepner; 01.10.2013

Пытаться:

find test/*.pdf | xargs -I % pdftk % cat output all.pdf

Как я уже сказал в своих комментариях к другим ответам, xargs - самый эффективный способ сделать это.

РЕДАКТИРОВАТЬ: я не видел, чтобы вам нужна была пустая страница, но я полагаю, вы могли бы передать find выше какой-либо команде, чтобы поместить пустую страницу между ними (аналогично соединению списка-> строки). Я предпочитаю этот способ, так как он больше похож на FP.

person Adam Gent    schedule 01.10.2013
comment
Вы не избегаете пространств. Это должно быть find test/*.pdf -print0 | xargs -0 -J % pdftk % cat output all.pdf - person jaygooby; 28.05.2015