Как настроить {} в команде find -exe c, чтобы она отображала имя папки вместо полного пути? - PullRequest
0 голосов
/ 26 февраля 2020

Запуск Debian Buster 10.3 и bash "GNU bash, версия 5.0.3 (1) -релиз (x86_64-p c - linux -gnu)"

data.exe - это программа Windows, которая создает файл данных xml с контрольными суммами для каждого файла в каталоге:

data.exe -t folderA /home/user/data/FolderA

-t - дескриптор тега. Я хотел бы, чтобы он отображал имя папки в каждом полученном файле xml вместо полного пути. Имя файла - это имя папки. Таким образом, имя файла: FolderA.dat

data.exe запускается в Linux через wine

Команда или сценарий bash должны быть в состоянии выполнить описанное действие периодически

/home/user/data/
/home/user/data/FolderA
/home/user/data/FolderB
...
/home/user/data/FolderZ

В Debian:

find /home/user/data/ -type d -print -exec wine data.exe -t {} -o {}.dat {} \;

создает xml файл правильно как FolderA.dat в пути / home / user / data /

Однако, -t дескриптор тега показывает полный путь:

<tag>/home/user/data/FolderA</tag>

вместо желаемого имени папки:

<tag>FolderA</tag>

Итак, есть ли способ изменить вывод {} так, как мне нужно? Я прочитал и перепробовал больше комбинаций, чем мог вспомнить. Даже назначил переменную $ pwd и настроил эту переменную, но не может передать эту переменную в -exe c, как если бы это было ожидаемое {}. Если бы меня попросили, я мог бы вставить свой файл истории, чтобы любой мог увидеть миллионы тестов, которые я выполнял как энтузиаст Linux. Если путь к go - это bash сценарий вместо однострочной команды, добро пожаловать. Через три дня я должен остановиться и попросить помощи.

Заранее спасибо,

Редактировать: 2020-02-26_16: 30GMT

Только одна проблема: пробел ' ' и круглые скобки '()' не интерпретируются. Backsla sh \ обычно используется для экранирования этих специальных символов. Например. из командной строки

user@debian:~$ wine data.exe -o Folder\ Beta.dat /home/user/data/Folder\ Beta

выводит теги Folder Beta.dat и -t правильно

Кажется, что find выводит путь как есть, поэтому оболочка не может правильно интерпретировать путь. Использование sed может помочь:

eg. /home/user/data/Folder (Zeta)

find /home/user/data/ -type d | sed -e 's/ /\\ /g' | sed -e 's/(/\\(/g' | sed -e 's/)/\\)/g'

выходы

/home/user/data/Folder\ \(Zeta\)

но как получить эти выходные данные как входные данные в -exec sh -c части команды find?

В следующем примере:

/home/user/data/
/home/user/data/FolderAlpha
/home/user/data/Folder Beta
/home/user/data/Folder-Gamma
/home/user/data/Folder(Delta)
/home/user/data/Folder[Epsilon]

/home/user/data/FolderAlpha
outputs FolderAlpha.dat and -t tag correctly

/home/user/data/Folder Beta
Aborted processing due to errors!

/home/user/data/Folder-Gamma
outputs Folder-GammaAlpha.dat and -t tag correctly

/home/user/data/Folder(Delta
Aborted processing due to errors!
/home/user/data/Folder(Delta: 1: /home/user/data/Folder(Delta: Syntax error: "(" unexpected
/home/user/data/FolderDelta)
Aborted processing due to errors!
/home/user/data/FolderDelta): 1: /home/user/data/FolderDelta): Syntax error: ")" unexpected

/home/user/data/Folder[Epsilon
outputs Folder[Epsilon.dat and -t tag correctly
/home/user/data/FolderEpsilon]
outputs FolderEpsilon].dat and -t tag correctly

1 Ответ

0 голосов
/ 26 февраля 2020

Вы можете использовать расширение параметра оболочки в форме ${<i>parameter</i>##<i>word</i>} для удаления заголовка пути:

find /home/user/data/ -type d -print -exec sh -c 'wine data.exe -t ${0##*/} -o {}.dat {}' {} \;

… одна проблема: пробел ' ' и скобки '()'

Для этого нам просто нужно процитировать имена в трех местах, где они появляются в команде оболочки:

find /home/user/data/ -type d -print -exec sh -c 'wine data.exe -t "${0##*/}" -o "{}".dat "{}"' {} \;
...