#linux #bash #shell
Вопрос:
Я новичок в написании сценариев оболочки, поэтому сделаю все возможное, чтобы обобщить все.
Я пишу сценарий с целью зайти в каталог и найти файл (readme.txt) в каждой вложенной папке и следуйте инструкциям, указанным в файле (readme.txt).
Код, который я написал до сих пор:
#! /bin/bash # Creating directory that the files are going to be moved into if ! (mkdir /dir1/dir2/backupdirgt; /dev/null); then echo "Directory already exists. " else echo "Directory successfully created. " fi # Moving old files to backup directory cd /dir1/dir2/maindir-* find /dir1 -mindepth 1 -type f -name "readme.txt" | while read z do if grep -i move "$z" gt; /dev/null; then mv /xdir0/$z /dir1/dir2/backupdir # /xdir0/ is the parent directory of /xdir1/ # readme.txt file does not include /xdir0/ so I added it when moving the files fi done
Выход по току: /dir1/dir2/maindir/subfolder1/readme.txt
В «maindir» есть несколько вложенных папок.
основной каталог/подпапка1 основной каталог/подпапка2 основной каталог/подпапка3
В каждой вложенной папке есть readme.txt файл. Содержание readme.txt выглядело бы примерно так:
Date: 2021-08-12 Applicable Version: xx.x Description: Quick summary of files Steps to apply: 1. move the following files into a backup location * xdir1/xdir2/xdir3/xdir4/filename-*.jar * xdir1/xdir2/xdir3/xdir4/filename1-*.jar 2. done. work completed.
Сценарий будет анализировать каждую строку после того, как будет распознано «перемещение», и остановится на «Сделано». Строка «Работа завершена», поскольку все файлы были перемещены в созданный мной каталог резервной копии.
Любая помощь будет очень признательна.
Комментарии:
1. Я что точное содержание
readme.txt
? Если нет, отредактируйте свой вопрос и укажите точное содержание.2. Привет, Дэвид, «Дата», «Применимая версия» и «Описание» были добавлены из readme.txt файл. Это точное содержание. К вашему сведению — Между «Датой», «Применимой версией» и «Описанием» в readme.txt файл. Это не позволило бы удалить пробелы между ними, когда я редактировал сообщение.
3. Я отформатировал текстовый файл для вас. Дважды проверьте, что теперь он отражает правильное
readme.txt
содержимое. (включая интервал и то , действительно ли строки, в которых есть файлы для перемещения, начинаются с a*
, и что строки1. move
и действительно начинаются с2. Done ...
1.
и2.
, и может ли быть более одного набора 1. переместить` и2. Done ...
строки.)4. Спасибо тебе, Дэвид. Я убрал пробелы и сменил «Готово. Работа завершена.» до «сделано. работа завершена». Да, строки, в которых есть файлы для перемещения, начинаются с * и 1. переместить и 2. готово, начинаются с 1. и 2. Я полагаю, что можно было бы добавить еще несколько строк, но пока я хотел оставить все как есть и добавить к нему позже.
Ответ №1:
Вы можете использовать mkdir -p newfolder
, который создаст его, или молча продолжить, если папка уже существует. Таким образом, вам не придется проверять, существует ли папка.
Вам не нужна sleep 1
На самом деле вы можете сначала использовать find -mindepth 1 -type f -name "readme.txt"
, чтобы найти папки, в которых у вас есть файл readme:
find /dir1 -mindepth 1 -type f -name "readme.txt"|while read z do if grep -i move "$z" gt; /dev/null;then ... do your mv magic fi done
Комментарии:
1. Я обновил свой исходный код, чтобы отразить внесенные изменения. Однако при запуске сценария я получаю следующую ошибку — строка 77: синтаксическая ошибка: неожиданный конец файла
2. нужно ли нам угадывать, как выглядит весь ваш сценарий? 🙂 Эта ошибка предполагает, что некоторые из
if
них неправильно закрыты или петли не закрыты.. Поделитесь всем своим сценарием или попробуйте выполнить локальную отладку в том месте, где возникла ваша проблема3. Вот и весь сценарий, который я запускаю. Исправлена ошибка «неожиданный конец файла», и теперь код работает нормально (удален для цикла). Однако он не считывает путь к файлам .jar, указанным внутри readme.txt файл и переместите их в созданный мной каталог резервной копии. Вместо этого он перемещает readme.txt сам файл помещается в папку /dir1/dir2/maindir.
4. Похоже, что переменная $z-это pwd или путь к каталогу readme.txt файл. Как я могу вместо этого указать путь к каталогу для файла .jar?
Ответ №2:
Лучший способ-использовать трубу, вы начинаете звонить find
:
# find all 'readme.txt' files from "$DIR" and subdirectories and make a loop # for each one. your_backup_location=/home/user/blah/blah/foo/bar find "$DIR" -name 'readme.txt' -print | while read file do # Assuming this is executed in subdirectory # xdir1/xdir2/xdir3/xdir4, where readme.txt was found... # $file contains the readme.txt full path from starting dir. echo "executing commands from $file" gt;amp;2 # print it on stderr ( # this will start a subshell, so we can work in the directory where readme.txt is. cd "$(dirname "$file")" # move to dir where readme.txt is located. . readme.txt # read commands from readme.txt file. Protect comment lines with # char. # as commands are read into the shell, no need to export the # shell variable ${your_backup_location} (see below) ) # exit subshell, so we are back in start directory. done
и readme.txt
формат должен быть текстовым файлом с комментариями оболочки (объясняющим в комментариях, что нужно сделать), перемежающимся командами оболочки для выполнения:
# Date: 2021-08-12 # Applicable Version: xx.x # Description: Quick summary of files # Steps to apply: # 1. move the following files into a backup location # * xdir1/xdir2/xdir3/xdir4/filename-*.jar mv filename-*.jar ${your_backup_location} # * xdir1/xdir2/xdir3/xdir4/filename1-*.jar mv filename-*.jar ${your_backup_location} # 2. done. work completed.
Таким образом, вы запустите подобласть в каждом каталоге, в котором у вас есть readme.txt
файл. Вы можете указать множество фильтров по find
команде, поэтому старайтесь выводить только то, что необходимо для выполнения какой-то реальной работы, и не пытайтесь создавать подобласть для каждого подкаталога просто для того, чтобы ничего не делать. И не используйте find
каждый раз просто спускаться на один уровень, так как у вас будет много find
запущенных процессов, которые почти ничего не будут делать.
Идея состоит в том, чтобы не выполнять ненужную обработку, если у вас нет строгих правил форматирования для описания действий, которые необходимо выполнить. В этом случае комментарии оболочки позволяют вам полностью описать операции, в то время как вы можете лучше описать операции с помощью допустимых команд оболочки. Это экономит много grep
и sed
используется в других ответах.