Сценарій Bash, щоб знайти всі папки, що містять певний файл, і скопіювати новий файл у ці папки


1

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

Ось що я маю досі:

#!/bin/sh
dir=/Documents
find "$dir" -name Sample.doc -printf "%p\n" | sort -nr | while read -r i; do
  echo "$i"
  done

Це працює, щоб перерахувати всі Sample.docфайли та їх папки в Documentsпапці.

Однак я не можу знайти спосіб витягти шлях із цих папок, щоб скопіювати у них новий файл.

Будь-яка допомога буде вдячна.

Відповіді:



0

Я думаю, ти майже там. Ви можете замінити %pз %hв -printfвираженні:

% h: провідні каталоги імені файлу (усі, крім останнього елемента). Якщо ім'я файлу не містить косої риски (оскільки він знаходиться в поточній директорії), специфікатор% h розширюється на ".".

тож команда буде чимось на зразок:

find "$dir" -name Sample.doc -printf "%h\n" | sort -nr | while read -r i; do cp SomeFile "$i"; done

до речі, навіщо sortпотрібна частина?


0

Використання %hнатомість %pвже було запропоновано в іншій відповіді, але я хотів би додати деякі вдосконалення, щоб зробити ваш код більш надійним. Якщо, наприклад, каталог, що відповідає, містить у своєму імені символ нового рядка, ви, в кращому випадку, закінчите пропущені каталоги та отримаєте кілька повідомлень про помилки від cp . У гіршому випадку ви можете перезаписати файли в будь-якій точці вашої системи.

Тому замість цього спробуйте зробити це так:

find "$dir" -name Sample.doc -printf "%h\0" | xargs --null -L1 cp SomeFile

Нуль ACSII гарантовано ніколи не відображатиметься в жодних іменах, тому на відміну від \nцього він працює як надійний роздільник для проходження шляхів. --nullговорить xargsпро використання \0в якості роздільника входу. Потім він виконає задану команду ( cp Somefile) один раз для елемента, що пройшов через трубу, додавши відповідний елемент як додатковий аргумент.


0

В bash:

shopt -s nullglob globstar
for i in "$dir"/**/Sample.doc
do
    cp 'new file' "$(dirname "$i")"/
done

У рибі:

for i in $dir/**Sample.doc
    cp 'new file' (dirname $i)/
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.