2017-01-30 2 views
1

У меня есть эта функция, где входные параметры искали строку и входной файл. Функция работает с файлами:Функция в цепи цепей

f_highlite() { 
    sed -e 's/\($1\)/\o033[91m\1\o033[39m/g' $2 
} 

Теперь я хотел бы использовать эту функцию в трубе. Как это должно быть изменено?

ps aux | grep java | f_highlite "Xms" - 

PS: Я не уверен, как точно назвать этот вопрос. Если у вас есть лучшее предложение, скажите это. ;]

+2

Когда вы запускаете цепочку труб, что вы ожидаете? Что на самом деле происходит? Что, если есть, сообщения об ошибках вы получаете? Каков ожидаемый и фактический результат? Наконец, помните, что переменные (например, '$ 1') не расширяются внутри строк с одним кавычком (например,' echo '$ 1'' внутри функции печатает буквальный '$ 1', а не расширяется до первого аргумента). –

+0

Я ожидаю, что эта функция (которую я плохо назвал:]) выделит _searched string_. Например, у меня есть команда loooong java и вы хотите выделить параметр * Xms *. Я забыл правило о строках с одним кавычком, которое было правильным по hek2mgl в ответе. – waldauf

+0

@waldauf Имейте в виду, что вам нужно убедиться, что первый аргумент правильно экранирован; Строгие команды 'sed' динамически не являются тривиальной задачей. – chepner

ответ

3

Во-первых, вам нужно использовать двойные кавычки, иначе $1 бы не получить расширен:

f_highlite() { 
    sed -e "s/\($1\)/\o033[91m\1\o033[39m/g" "$2" 
} 

Btw, вам необходимо убедиться, что $1 не будет содержать символы, которые понятны sed, как синтаксические элементы. Для Xms все в порядке.


В этой теме, вы можете передать - в качестве второго аргумента функции, потому что sed понимает - как STDIN: (! Спасибо @chepner)

ps aux | grep Java | f_highlite "Xms" - 

+1

Здесь нет необходимости в 'xargs'. POSIX 'sed' распознает (в соответствии с [Guideline 13] (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02))' -' как входной файл, означающий стандартный ввод. – chepner

+0

@chepner Спасибо. Также это не работает вообще в текущей форме, потому что 'xargs' может вызывать исполняемые файлы, но не функцию bash. ;) Имеет смысл, но пропустил это. Просто понял, что ... Работа над исправлением ... – hek2mgl

+0

@chepner '-' работает pefect! Я уже готовил что-то с помощью 'xargs ... bash -c 'f_highlight" и 'export -f' .. Использование' -' - простое решение здесь! – hek2mgl

0

Есть два другие подходы, о которых вы, возможно, захотите узнать, поскольку не все команды будут поддерживать трюк -.

Первый имеет функцию, которая работает с потоками и не принимает файл в качестве входа. Вы можете сделать это путем удаления $ 2 в конце концов, и изменения, как вы вызываете функцию

f_highlite() { 
    sed -e 's/\($1\)/\o033[91m\1\o033[39m/g' 
} 

f_highlite <"Xms" 

Это будет перенаправлять содержимое файла и подключить его к стандартному входу функции (и, следовательно, к тому, что из sed).

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

f_highlite() { 
    sed -e "s/\($1\)/\o033[91m\1\o033[39m/g" "$2" 
} 

f_highlite < <(<"Xms") 

Это (по крайней мере, концептуально) создает буфер FIFO, который имеет свой вход подается с содержимым файла, а его выход подключен к входу функции. Ключ здесь состоит в том, что <(<"Xms") становится именем файла (вы можете попробовать распечатать его имя, чтобы подтвердить это).

Смежные вопросы