Вопрос

Я пытаюсь выполнить следующую команду:

find . -iname '.#*' -print0 | xargs -0 -L 1 foobar

где "foobar" - это псевдоним или функция, определенная в моем файле .bashrc (в моем случае это функция, которая принимает один параметр).Очевидно, xargs не распознает их как вещи, которые он может запускать.Есть ли умный способ исправить это?

Это было полезно?

Решение

Поскольку только ваша интерактивная оболочка знает об псевдонимах, почему бы просто не запустить псевдоним без разветвления через xargs?

find . -iname '.#*' -print0 | while read -r -d '' i; do foobar "$i"; done

Если вы уверены, что в ваших именах файлов нет новых строк (черт возьми, с чего бы это?), вы можете упростить это до

find . -iname '.#*' -print | while read -r i; do foobar "$i"; done

или даже просто find -iname '.#*' | ..., поскольку каталог по умолчанию является . и действие по умолчанию таково -print.

Еще одна альтернатива:

 IFS=$'\n'; for i in `find -iname '.#*'`; do foobar "$i"; done

сообщаю Bash, что слова разбиваются только на новые строки (по умолчанию: IFS=$' \t\n').Однако вам следует быть с этим поосторожнее;некоторые скрипты плохо справляются с измененным $IFS.

Другие советы

Используя Bash, вы также можете указать количество аргументов, передаваемых вашему псевдониму (или функции), следующим образом:

alias myFuncOrAlias='echo'  # alias defined in your ~/.bashrc, ~/.profile, ...
echo arg1 arg2 | xargs -n 1 bash -cil 'myFuncOrAlias "$1"' arg0
echo arg1 arg2 | xargs  bash -cil 'myFuncOrAlias "$@"' arg0

Это не работает, потому что xargs ожидает, что сможет exec тот самый программа задается в качестве его параметра.

С тех пор как foobar в вашем случае это просто bash псевдоним или функция, в которых нет программы для выполнения.

Хотя это предполагает начало bash для каждого файла, возвращенного find, вы могли бы написать небольшой сценарий оболочки таким образом:

#!/bin/bash
. $(HOME)/.bashrc
func $*

а затем передайте имя этого скрипта в качестве параметра xargs

Обычно я использую find следующим образом:

find . -iname '' -exec cmd '{}' \;

'{}' будет заменено именем файла, и \;это необходимо для завершения цепочки выполнения.Однако, если это не работает с вашей функцией, вам может потребоваться запустить ее через bash:

find .. |sed -e "s/.*/cmd '&'/"|bash

Find печатает каждый файл в строке, sed просто добавляет к нему префикс вашей команды, а затем передает его в bash для выполнения.Сначала пропустите |bash, чтобы посмотреть, что произойдет.

попробуй

find . -iname '.#*' -print0 | xargs -0 -L 1 $(foobar)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top