знайти з -execdir


16

Коли я біжу findз -execdirI не одержати результати , які я очікував.

Наприклад:

mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
   ├── c
   └── foo
└── foo

Каталог cне містить fooфайлу. Як я можу findвідвідувати та робити щось локально у кожному каталозі?

Відповіді:


18

Для кожного відповідного файлу (тобто кожного каталогу) findперемикається на каталог, який містить його (тобто його батьківський каталог) і виконує вказану команду. Оскільки команда не використовує назву збігу, вона ніколи не буде діяти у всіх каталогах. Для цього конкретного дерева каталогу ви робите

(cd . && touch foo)        # because ./a matches
(cd ./a && touch foo)      # because ./a/b matches
(cd ./a/b && touch foo)    # because ./a/b/c matches

Щоб створити файл у кожному каталозі, ви можете просто використовувати -execзамість цього -execdir, якщо ваша реалізація findдозволяє {}всередині аргументу (більшість з них, і я думаю, що всі):

find . -type d -exec touch {}/foo +

Для перенесення POSIX вам потрібно буде виконати збірку імені каталогу та базового імені файлу вручну.

find . -type d -exec sh -c 'touch "$0/foo"' {} \;

або (трохи швидше)

find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +

Крім того, ви можете використовувати рекурсивну підстановку підстановок башів. findБудьте уважні, що (на відміну від відповідної функції в ksh і zsh, і на відміну від вашої команди) bash повторюється під символічними посиланнями на каталоги.

shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done

Рішення zsh:

touch ./**/(e\''REPLY+=foo'\')

FYI: man bashстани під "-c": аргументи після command_string присвоюються позиційним параметрам, починаючи з $ 0, однак "для d" буде повторюватися через позиційні параметри, починаючи з $ 1. "_" - це текст, який призначається $ 0 і не буде використовуватися.
Чад Скітерс

3

Команда виконується у кожному каталозі, що містить відповідний файл. Оскільки cвін не містить каталогу, він не збігається і, отже, не запускатиметься там.

Рішення полягає в тому, щоб додати ім'я каталогу до аргументу execdir, наприклад:

find . -type d -execdir touch {}/foo \;

2

З man file

   -execdir command {} +
          Like  -exec,  but  the  specified  command is run from the subdirectory containing the matched file

Ваш відповідний каталог cживе в bкаталозі, так що звідки виконується exec. Він буде працювати, як ви очікуєте, якщо ви шукаєте файли замість каталогів.

Ви, напевно, могли б досягти того, що хочете, надсилаючи каталоги, до xargsяких буде наданий повний список каталогів.

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