Видалити шлях з команди пошуку висновку


29

У мене є сценарій bash для розгортання коду з бета-середовища у виробниче середовище, але в даний час я маю додати список файлів до файлу txt маніпулятивно, і коли-небудь я пропускаю їх. В основному мій сценарій розгортання котів / циклів копіює файли. (експорт / імпорт дБ, але це не має значення ...

У будь-якому разі, я хотів би скористатися findкомандою для створення списку файлів, змінених за останні 14 днів. Проблема в тому, що мені потрібно викреслити шлях, ./щоб сценарій розгортання працював.

Ось приклад використання команди find:

знайти. -тип f -mtime -14> розбудувати.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?

Спасибі!


3
Чи є причина, що ви не можете просто використовувати rsync для цього? Це здається так, ніби ви, можливо, намагаєтесь винайти колесо і зробити його трикутником.
ThatGraemeGuy

дійсний пункт, проте перед розгортанням буде розглядатися розбудова.txt, і все, що потребує виправлення, видаляється
Mikey1980,

1
Можливо, запустіть rsync в --dry-runрежимі та виведіть його у файл для огляду?
Зоредаче

Відповіді:


36

Ви можете використовувати параметр -printfкомандного рядка, %fщоб надрукувати лише ім'я файлу без будь-якої інформації каталогів

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

або ви можете використовувати sed, щоб просто видалити ./

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

Я вважаю, що вам потрібно уникнути /..
ЄЕАА

5
Не тоді, коли ви використовуєте |як роздільник.
user9517 підтримує GoFundMonica

3
Використання %fзніме всі каталоги, а не лише ./. Це призведе до порушення сценарію його розгортання, якщо будь-який з файлів, повернених файлами find, розташований у підкаталогах.
Джеймс Снерінгер

2
@Iain Вам потрібно втекти .. І, можливо, найкраще використовувати стартовий якір:s|^\./||
Джеймс О'Горман

12
Використовуйте %Pзамість %f. Це просто відрізає шлях, вказаний у командному рядку.
Дійсно

11

./Повинно бути нешкідливим. Більшість програм трактуються /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повертає повний шлях кожного знайденого файлу, мінус шлях , вказаний в командному рядку, аж до і включаючи перший слеш. Це дозволить зберегти будь-які підкаталоги в структурі вашого каталогу.


1
./Приставка насправді функція; без цього вихідний конвеєр для інших команд не буде працювати належним чином, наприклад, для імен файлів, які починаються з тире.
трійка

1
@tripleee - Я розумію корисність цього, але ОП спеціально запитав, як зняти його, оскільки це спричиняло проблеми для його сценарію розгортання. Звичайно, можуть бути кращі способи зробити те, що йому потрібно зробити, але це кроляча нора, що виходить за рамки запитуваного.
James Sneeringer

7

Чому потрібно знімати ./? Це дійсно мати шлях. Так

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

просто гаразд!

Але якщо ви хочете зняти ім'я каталогу у пошуку, ви можете використовувати %Parg для -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

3

Ну, у вас є кілька варіантів. Ви можете скористатися -printfопцією пошуку, щоб роздрукувати лише ім'я файлу, або ви можете скористатися інструментом, як 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/^\.\///'

Чи можете ви надати мені приклад його використання? Вибачте, Linux насправді не є моєю фортецею
Mikey1980,

2
Подивіться ще, є приклади.
Зоредаче

Домовились - просто спробуйте, вам нічого не зашкодить, комбінуючи знахідку і sed.
ЄЕАА

3

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

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

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


2

Швидке рішення, якщо я правильно розумію питання, використовує cutна виході findкоманди:

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

Це позбавить перших символів з кожного рядка результату (у вашому випадку ./). Напевно, не найкраще рішення, але працює за вашим сценарієм.


1

sed ідеально підходить для подібних речей.

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

1

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

Моя пропозиція полягала б у використанні розширення параметрів оболонки для позбавлення символів від кожного імені файлу:

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

Пам’ятайте, що висновок цього НЕ обмежується нулем, тому, хоча це може бути достатньо для перевірки очного яблука, жодне з цих рішень не створює файл розширення.txt, який безпечно використовувати для автоматизації, якщо ви не впевнені у своєму джерелі назви файлів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.