Назад | Перейти на главную страницу

Удалить путь из вывода команды find

У меня есть сценарий bash для развертывания кода из бета-среды в производственную среду, но в настоящее время мне нужно вручную добавить список файлов в текстовый файл, и иногда я пропускаю некоторые. В основном мой сценарий развертывания cat / loops копирует файлы. (также экспортирует / импортирует db, но это не имеет отношения ... lol)

В любом случае, я бы хотел использовать find команда для создания списка файлов, измененных за последние 14 дней. Проблема в том, что мне нужно удалить путь ./ чтобы скрипт развертывания работал.

Вот пример использования команды find:

найти . -type f -mtime -14> deploy.txt

Вот строка, что кошки deploy.txt в моем сценарии развертывания:

for i in `cat deploy.txt`; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done

Есть идеи, как это сделать с помощью сценариев bash?

Спасибо!

Вы можете использовать -printf параметр командной строки с %f для печати только имени файла без какой-либо информации о каталоге

find . -type f -mtime -14 -printf '%f\n' > deploy.txt

или вы можете использовать sed, чтобы просто удалить ./

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt

В ./ должен быть безвредным. Большинство программ будут лечить /foo/bar и /foo/./bar как эквивалент. Я понимаю, что это выглядит не очень красиво, но, судя по тому, что вы опубликовали, я не вижу причин, по которым это может привести к сбою вашего скрипта.

Если вы действительно хотите его снять, sed наверное, самый чистый способ:

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt

Если вы работаете в системе с GNU find (например, в большинстве систем Linux), вы можете сделать это за один раз с find -printf:

find . -type d -mtime 14 -printf "%P\n" > deploy.txt

В %P возвращает полный путь к каждому найденному файлу минус путь, указанный в командной строке, до первой косой черты включительно. Это сохранит все подкаталоги в вашей структуре каталогов.

Зачем нужно снимать ./? Допустимо иметь в пути. Так

cp -i dir1/./somefile dir2/./somefile

просто нормально!

Но если вы хотите удалить имя каталога в find, вы можете использовать %P аргумент к -printf.

человек найти (1) говорит:

         %P     File's name with the name of the  command  line  argument
                 under which it was found removed.

Пример

$ find other -maxdepth 1
other
other/CVS
other/bin
other/lib
other/doc
other/gdbinit
$ find other -maxdepth 1 -printf "%P\n"

CVS
bin
lib
doc
gdbinit

Обратите внимание на первую пустую строку! Если вы хотите избежать этого, используйте -mindepth 1

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit

Решение "find -printf" не будет работать во FreeBSD, потому что у find нет такой опции. В этом случае может помочь AWK. Он возвращает фамилию ($ NF), поэтому может работать на любой глубине.

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'

PS: взято из книги Д. Тэнсли "Программирование оболочки Linux и Unix"

Что ж, у вас есть несколько вариантов. Вы можете использовать -printf в find, чтобы распечатать только имя файла, или вы можете использовать такой инструмент, как sed, чтобы просто вырезать ./.

# simply print out the filename, will break if you have sub-directories.
find . -mtime -14 -printf '%f\n'

# strip a leading ./
find .  -mtime -14 | sed -e 's/^\.\///'

Быстрое решение, если я правильно понял вопрос, использует cut на выходе find команда:

$> find . -type f -mtime -14 | cut -b 3- > deploy.txt

Это приведет к удалению первых символов из каждой строки результата (в вашем случае ./). Возможно не лучшее решение, но работает в вашем сценарии.

sed идеально подходит для такого рода вещей.

$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt

Я не знаю, о каких именах файлов мы говорим, но все, что содержит пробелы или символы новой строки, ставит под угрозу большинство решений.

Я предлагаю использовать расширение параметра оболочки, чтобы удалить символы из каждого файла:

find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt

Если вам действительно нравятся каналы, вы можете использовать «безопасный» разделитель, например ноль, с xargs для получения каждого имени файла:

find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt

Помните, что результат этого НЕ с нулевым разделителем, поэтому, хотя этого может быть достаточно для проверки на глаз, ни одно из этих решений не создает файл deploy.txt, который можно безопасно использовать для автоматизации, если вы не уверены в именах исходных файлов.