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

У меня есть сценарий bash для развертывания кода из бета-среды в производственную среду, но в настоящее время я должен добавить список файлов в файл txt manaully, а иногда я пропустил некоторые из них. В основном мой сценарий развертывания 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?

Спасибо!

21 голос | спросил Mikey1980 28 Jam1000000amSat, 28 Jan 2012 00:59:14 +040012 2012, 00:59:14

8 ответов


26

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

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

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

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt
ответил Wayne Werner 6 TueEurope/Moscow2016-12-06T15:39:48+03:00Europe/Moscow12bEurope/MoscowTue, 06 Dec 2016 15:39:48 +0300 2016, 15:39:48
9

./ должен быть безвредным. Большинство программ будут обрабатывать /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 возвращает полный путь к каждому найденному файлу, минус путь, указанный в командной строке, вплоть до первого слэш. Это сохранит любые подкаталоги в структуре вашего каталога.

ответил James Sneeringer 28 Jam1000000amSat, 28 Jan 2012 01:36:02 +040012 2012, 01:36:02
5

Зачем вам нужно отключить ./? Это допустимо иметь в пути. Итак,

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

все в порядке!

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

man find (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
ответил TrueY 29 Maypm13 2013, 14:01:24
3

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

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

PS: взято из книги D.Tansley «Linux and Unix shell programming»

ответил user221341 26 Maypm14 2014, 20:12:11
2

У вас есть несколько вариантов. Вы можете использовать опцию -printf в поиске, чтобы распечатывать только имя файла, или вы можете использовать инструмент, например sed, чтобы просто вырезать ---- +: = 1 =:. + ----

./
ответил Zoredache 28 Jam1000000amSat, 28 Jan 2012 01:06:12 +040012 2012, 01:06:12
2

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

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

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

ответил Alessandro Dotti Contra 28 Jam1000000amSat, 28 Jan 2012 01:12:10 +040012 2012, 01:12:10
1

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

$ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt
ответил EEAA 28 Jam1000000amSat, 28 Jan 2012 01:08:09 +040012 2012, 01:08:09
1

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

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

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

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

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

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

ответил ghoti 21 FebruaryEurope/MoscowbTue, 21 Feb 2017 20:59:42 +0300000000pmTue, 21 Feb 2017 20:59:42 +030017 2017, 20:59:42

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132