Я пытаюсь объединить все файлы в подкаталоге в новый файл и дать новому объединенному файлу то же имя, что и в подкаталоге, и я понятия не имею, как это сделать в Bash. Вот как я подошел к этому: у меня есть несколько каталогов, каждый с уникальным именем файла (с пробелами!). В каждом из этих каталогов есть несколько файлов с числовыми именами, например:

Home/Unique name/1.pdf  
Home/Unique name/2.pdf  
Home/Unique name/3.pdf  
Home/Unique name/4.pdf  
....  
Home/Other Unique name/1.pdf  
Home/Other Unique name/2.pdf  
Home/Other Unique name/3.pdf  
Home/Other Unique name/4.pdf

Я хотел бы написать скрипт bash (из Home каталога) для:

  1. Перейдите в каждый уникальный каталог и выполните команду для каждого из файлов в этом каталоге (в моем случае скопируйте их все в другой каталог).
  2. Затем я написал другой скрипт script.sh который будет выполнять другую команду (в этом случае объедините все PDF-файлы в один файл, temp.pdf). Затем я хотел бы переименовать этот файл temp.pdf после каталога Unique name.pdf (с пробелами).
  3. Я должен буду следовать этому процессу для ряда подкаталогов.

Я пытался найти решение с несколькими циклами for, while и использованием команды find, но я не достаточно удобен с bash, чтобы удобно отлаживать или использовать эти переменные с какой-либо степенью достоверности. Я также уверен, что есть более эффективный способ сделать то, что я делаю, но я запустил сценарий вместе в течение определенного периода времени.

2 ответа2

1

POSIX способ заключается в использовании print . -type d ... | while read f; do , но если вы не одержимы 100% мобильностью, я бы не стал беспокоиться об этом. Если у вас есть bash 4+ и pdfunite (установленные по умолчанию на моем Ubuntu 13.04), вы можете сделать это в две строки:

shopt -s globstar
for f in ./**/; do pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Обратите внимание, что shopt -s globstar должен находиться на отдельной строке от всего остального. При включенном globstar ** рекурсивно расширяется на все файлы и каталоги в текущем каталоге. Поскольку файлы не могут содержать / в своих именах, **/ будет расширяться только до каталогов. Я использую ./**/ в маловероятном случае, когда ваши каталоги начинаются с дефиса (-), так как это может вызвать проблемы, так как многие программы рассматривают все, что начинается с - как вариант.

Как написано, это не будет копировать PDF-файлы в другой каталог, но добавить его довольно просто:

for f in ./**/; do cp "$f"/*.pdf /target/dir/; pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Если вы хотите использовать свой собственный скрипт комбинирования PDF, просто измените строку в соответствии с вашими предпочтениями, но помните, что суть сценариев оболочки - это сборка уже существующих команд.

Вот несколько более портативная версия:

print . -type d -print0 | while read -d $'\0' f; do
  pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"
done
0
  1. Создайте for цикла с переменным find /home/ -type f -name "*.pdf" в качестве переменной
  2. Скопируйте файлы туда, куда вам нужно, возьмите $ VARIABLE и обработайте его через sed / awk для удаления "/".

Разместите свой сценарий, и мы поможем вам его улучшить.

Вы всегда можете запустить сценарии с помощью bash -x для их отладки, или вы можете установить !#/bin/bash -x всегда выполнять в режиме отладки (многословно).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .