xargs и проблемы с подстановкой команд

Итак, у меня есть ужасный oneliner, который получает значение json, извлекает из него данные с помощью jq, а затем перебирает данные с помощью xargs. В конце он должен создать некоторый xml

legendary list-installed --json | jq '.[].title' | sed s/"\""/""/g | xargs -n1 -p -d "\n" -I {} echo '<button onclick="'$(legendary list-installed --json | jq 'map(if .title == "'{}'" then .app_name elif .title == "_" then "_" else "_" end)')'">'{}'</button>'

Прежде всего, я не использовал флаг -r с jq, потому что думал, что проблема может быть из-за него.

Ожидаемый результат должен быть примерно таким:

<button onclick=app name e.g. Coley> The Escapist 2 </button>

Пока что это работает (за исключением части имени приложения, так как именно здесь она начинает становиться странной)

Поскольку я вряд ли могу отлаживать с помощью jq внутри подстановки команд, я хотел проверить, какие xargs передаются в стандартный ввод через другую подстановку команд. Я изменил часть между двумя элементами кнопки {} на $(echo {}), которая все еще работает. Но случайно я передал его в wc -w, который выводит ОДИН, если содержимое {} на самом деле ДВА! изображение

❯ ./test.sh
<layout>
echo 'button onclick="[' '"_",' '"_",' '"_"' ']">Ape Out</button>' ?...^C⏎                                                                                                                                           
> cat test.sh
...'$(echo {})'</button>'

Если я просто повторю содержимое {}, он вернет это (я знаю, что это бесполезное эхо, это просто для согласованности): Второе изображение Когда я считаю слова внутри своей оболочки, а не внутри xargs

legendary list-installed --json | jq '.[].title' | head -n 1 | sed s/"\""/""/g | wc -w

он возвращает два.

Результат работы с set -x

❯ ./test.sh
+ echo '<layout>'
<layout>
+ legendary list-installed --json
+ jq '.[].title'
+ sed 's/"//g'
++ legendary list-installed --json
++ jq 'map(if .title == "{}" then .app_name elif .title == "_" then "_" else "_" end)'
++ echo '{}'
++ tee lolsu,txt
+ xargs -n1 -p -d '\n' -I '{}' echo 'button onclick="[' '"_",' '"_",' '"_"' ']">{}</button>'
echo 'button onclick="[' '"_",' '"_",' '"_"' ']">Ape Out</button>' ?...

Похоже, что он не заменяется правильно... Новая проблема заключается в том, как заставить его заменить {} реальным внутри подстановки.

TLDR: подсчет значения xargs возвращает единицу, в то время как передаваемый ввод должен состоять из двух слов (поскольку я повторяю строку, а не слово). При работе в оболочке он возвращает два (без использования xargs, obv)


person lolsu    schedule 18.10.2020    source источник
comment
$(echo {}) не сработает. {} должен быть аргументом xargs, а не в подоболочке. Это просто повторение буквального {}   -  person Barmar    schedule 18.10.2020
comment
@Barmar На самом деле это работает! похоже, что xargs реализовал $() самостоятельно. Демонстрация: изображение   -  person lolsu    schedule 18.10.2020
comment
Непонятно, что вы на самом деле пишите. Но если вы просто поместите $(echo {}) в командную строку, это по сути то же самое, что просто ввести {} в командную строку, поскольку $(...) заменяется выводом ....   -  person Barmar    schedule 18.10.2020
comment
Да, я это знаю, но странно то, что когда я передаю это в wc -w, там написано, что это только одно слово, тогда как явно 2 i.imgur.com/M50ThTY.png   -  person lolsu    schedule 18.10.2020
comment
Покажите, пожалуйста, командную строку в вопросе. По описанию сложно сказать, что происходит.   -  person Barmar    schedule 18.10.2020
comment
Готово - осталось еще 11 персонажей   -  person lolsu    schedule 18.10.2020
comment
Пожалуйста, используйте текст, а не изображение. Я не могу это прочитать.   -  person Barmar    schedule 18.10.2020
comment
Добавил немного текста   -  person lolsu    schedule 18.10.2020


Ответы (1)


Когда вы пишете

$(echo {} | wc -w)`

Входными данными для команды wc -w является строка {}. Это одно слово, так что результатом будет 1, и оно подставится вместо $(echo {} | wc -w). Это не замена чего-либо из xargs, потому что сначала выполняются подстановки команд, а результаты подставляются в командную строку.

Итак, аргумент, который получает xargs, содержит уже подставленный 1.

person Barmar    schedule 18.10.2020
comment
а почему эхо тогда работает внутри подстановки? - person lolsu; 18.10.2020
comment
Он повторяет буквальную строку {}. Почему это не должно работать? - person Barmar; 18.10.2020
comment
См. только что добавленный текст... Он повторяет реальное и единственное содержимое {}, то есть Ape Out. - person lolsu; 18.10.2020
comment
Когда у вас есть только $(echo {}), это то же самое, что просто писать {}. Затем xargs получает его в качестве аргумента и заменяет текущим элементом итерации. - person Barmar; 18.10.2020
comment
Проблема была, когда вы использовали $(echo {} | wc -w). Это заменяет вывод wc -w командой xargs, а не {} элементом итерации. - person Barmar; 18.10.2020
comment
Я предлагаю вам запустить свой скрипт с set -x, чтобы вы могли видеть порядок замен. - person Barmar; 18.10.2020
comment
Хм, вероятно, то же самое происходит и в первой подстановке, поэтому я задаю этот вопрос в первую очередь. Вы знаете, как я могу это исправить, чтобы вместо {} был контент?? О, я не видел часть set -x. я попробую это и отчитаюсь - person lolsu; 18.10.2020
comment
Я предлагаю вам написать сценарий оболочки, который получает текст в качестве аргумента и форматирует его по вашему желанию, и вызывать этот сценарий с помощью xargs. Выполнение всего этого в одну строку сведет вас с ума. - person Barmar; 18.10.2020
comment
Хорошо, я поместил его в другой сценарий оболочки, и я могу вызвать его. но я не могу добавить содержимое {} в аргументы, так как это та же проблема, что и раньше. Он отправляет буквально {}... - person lolsu; 18.10.2020
comment
Я просто использовал традиционный цикл for вместо xargs. Теперь работает как шарм. - person lolsu; 18.10.2020