Вы могли переключиться на lftp вместо того, чтобы использовать scp. Это дает Вам хороший последовательный интерфейс для передачи файлов по ftp, sftp и ssh включая автоматическое заполнение, которое Вы ищете и больше (т.е. подстановочные знаки).
lftp fish://user@machine
открывается соединение по ssh как Вы делают выше с scp. Много машин поддерживают sftp://также, который еще более хорош, по моему опыту.
Когда Вы вводите команду, которая включает неупомянутый шарик как .b*
или *.e*
, оболочка развернет это для Вас. Это происходит прежде find
когда-либо видит его.
У Вас, вероятно, есть файлы как .bashrc
, .bash_history
, и т.д. в Вашем $HOME
каталог. Таким образом, когда выполнено от $HOME
, Ваша команда превращается find ... -execdir ls -d .bashrc .bash_history ... \;
. Когда выполнено от других мест, .b*
шарик ничему не соответствует, таким образом, через него проходят. Это все еще не работает, как find -exec
ничего не делает с *
шарики. Если Вы хотели, чтобы шарик был расширен для -exec
, необходимо было бы вызвать оболочку, чтобы сделать это:
find ... -execdir sh -c 'echo globs: *' \;
Both the find command and the shell are capable of file globbing.
Это необычно -большинство команд НЕ способны выполнять подстановку и полностью полагаются на оболочку для расширения подстановок. Но find — это супер-пупер-мега-мощный пользовательский инструмент, с которым вы можете очень легко навредить себе!
Пример :при выполнении команды
find /path -iname *.txt
Первое, что происходит, это попытка оболочки найти все файлы, соответствующие *.txt в текущем каталоге. Если он их находит, он заменяет имена всех соответствующих файлов для глобуса, а затем вызывает команду find. Команда find никогда не увидит глобус , если это произойдет, оболочка расширит его до несуществования.
Но если в текущем каталоге нет файлов, соответствующих глобусу, оболочка метафорически пожимает плечами и пропускает глобус без изменений для поиска. Таким образом, в этот момент команда find (, которая понимает подстановочные знаки, помните ), выводит имена всех файлов, которые она находит в /path, которые соответствуют подстановочным знакам.
Таким образом, использование globs таким образом означает, что find будет вести себя по-разному в зависимости от содержимого текущего каталога. Это почти наверняка не то, что вы хотите!
Чтобы оболочка не вмешивалась в подстановочные знаки до того, как find их увидит, экранируйте подстановочные знаки с помощью соответствующего метасимвола оболочки в кавычках. Обычно это просто означает помещение ваших глобальных строк в одинарные кавычки, как здесь
find /path -iname '*.txt'
Remember, GLOBS ARE NOT REGEXES - the glob ".*" and the regex ".*" are very different and do not match the same strings!
Когда оболочка bash
не может найти файл, соответствующий заданному шаблону подстановки, он оставляет этот шаблон нераскрытым. Это приводит к тому, что в вашей команде find
ls
получает нерасширенный шаблон *.e*
в качестве аргумента. Утилита ls
не расширяет шаблоны подстановки имен файлов сама по себе, а полагается на то, что оболочка уже сделала это.
Это, скорее всего, ваша проблема с вашей последней командой find
, которая, кажется, может работать правильно только из вашего домашнего каталога, возможно, потому, что ваш домашний каталог содержит файлы, соответствующие шаблону (.bashrc
, например, соответствует .b*
). Если шаблоны не соответствуют чему-либо в текущем каталоге, шаблон будет передан ls
как есть, а поскольку ls
не расширяет шаблоны подстановки сам по себе, он не сможет перечислить какие-либо файлы.
Короче говоря, вы не можете вызвать ls
напрямую с помощью -execdir
или -exec
и дать ему шаблон подстановки имени файла.
Кроме того, вы говорите, что хотите перечислить файлы, соответствующие *.e*
, для «дальнейшей обработки». Я бы посоветовал не делать этого, а вместо этого выполнять эту обработку в самой команде find
. Причина этого указана в вопросе/ответе "Почему перебор вывода find является плохой практикой? ".
Итак, вместо того, что вы сейчас делаете, подумайте
find. -type f -name md.tpr -exec bash -O nullglob -O dotglob -c '
for pathname do
dirpath=${pathname%/md.tpr}
for e in "$dirpath"/*.e*; do
# process "$e" here!
done
done' bash {} +
Предполагается, что md.tpr
является обычным файлом, который необходимо найти. Команда find
находит пути ко всем этим файлам md.tpr
и загружает их пакетами во встроенный скрипт bash
.Скрипт bash
короткий:
for pathname do
dirpath=${pathname%/md.tpr}
for e in "$dirpath"/*.e*; do
# process "$e" here!
done
done
Это просто берет заданные аргументы, извлекает компонент каталога каждого (, удаляя строку суффикса /md.tpr
, которая, как мы знаем, присутствует, из пути )и циклически перебирает файлы, соответствующие *.e*
в каждый каталог (с $e
, содержащим путь к каждому совпадающему файлу, в свою очередь ).
Скрипт строки -запускается с установленными параметрами nullglob
и dotglob
, чтобы шаблон *.e*
удалялся полностью, если он не совпадает, и чтобы шаблон соответствовал скрытому имена.
Немного больше информации об использовании -exec
с find
можно найти в «Понимание опции -exec команды `find `».
Поскольку вы отметили этот вопрос тегом bash , вот как сделать то же самое в простом bash
цикле (для этого требуется bash
версия 4 или более поздняя):
shopt -s globstar nullglob dotglob
for pathname in./**/md.tpr; do
dirpath=${pathname%/md.tpr}
for e in "$dirpath"/*.e*; do
# process "$e" here!
done
done
Помимо отсутствия каких-либо проверок того, являются ли сопоставленные md.tpr
файлы обычными файлами или нет, это должно выглядеть очень похоже на скрипт в строке -, вызванный find
выше. Параметр оболочки globstar
в bash
включает глобус **
, который «рекурсивно» сопоставляется с подкаталогами.
Я ожидаю, что это будет немного медленнее, чем использование find
, но это может оказаться более удобным способом написания кода.
find ... -name '*.txt'
работы (да, да, одинарные кавычки) и дескрипторы те шарики правильно, но когда я передаю такие шарики-exec[dir]
, это перестало работать. Я сделал комментарий в своем сообщении об одинарных кавычках и никаких кавычках как в какой-то момент, я действительно пробовал все, так отбрасывание кавычек было первой вещью, которую я сделал, пытаясь выяснить, почему вещи перестали работать. Последний пример состоял в том, чтобы показать, что даже очевидная вещь не работала (да, я ожидал видеть.bashrc
,.bash_history
, и т.д.). – Wojtek Rzepala 10.11.2012, 01:12-exec
и-name
работайте по-другому.-name
действительно поддерживает шарики. – jw013 10.11.2012, 02:00