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

В общем, есть по крайней мере три способа сделать комбинацию find+ grep:

  1. grepшаблон`findкаталогнайти -спецификаторы-print`
  2. findкаталогнайти -спецификаторы-exec grepшаблон{} \;
  3. findкаталогнайти -спецификаторы-print | xargs grepшаблон

И, конечно, здесь grepнет ничего особенного; эти же три шаблона можно использовать для findплюс любая команда.

Номер 1, в некотором смысле, самый старый и самый простой способ, поскольку обратные кавычки всегда были способом захватить вывод одной команды и использовать его в командной строке другой. (В последнее время у меня сложилось впечатление, что есть более новый башизм, который лучше, чем обратные кавычки, и который используют все крутые ребята, но я думаю, что я старый -таймер. )Недостаток варианта №1 в том, что если findнаходит много файлов, может появиться ошибка "Слишком длинная командная строка".

Номер 2 — это специальная функция, встроенная в findдля выполнения комбинации find+ команда. Пока это хорошо, но у него есть два недостатка:(1 )он повторно -вызывает вспомогательную команду(grepили что-то еще )для каждого найденного файла, поэтому он может быть медленным, и (2 )если вспомогательной командой является grep, поскольку каждый вызов grepвидит одно имя файла, он не будет отображать имена файлов в совпадении, хотя вы можете обойти это, выполнив шаблон-exec grep{} /dev/null \;или, в наши дни, шаблон-exec grep -H{} \;.

И еще есть номер 3. Насколько я знаю, xargsбыл изобретен, чтобы обойти ограничения первых двух. Хотя xargsтеоретически является программой общего назначения -, я подозреваю, что на практике она почти никогда не используется с какой-либо парой программ, кроме findи grep. Он полностью устраняет недостаток #1; он будет работать с произвольным количеством найденных файлов. Это эффективно, хотя, если вам не повезет, он будет иногда вызывать grepодно последнее имя файла, а это означает, что вы все равно захотите использовать трюк /dev/nullили -H. И у него есть свой недостаток :— он не работает, если какое-либо из найденных имен файлов содержит пробелы. Но и это можно обойти:

findкаталогнайти -спецификаторы-print0 | xargs -0 grepшаблон

(Я бы очень хотел, чтобы xargsбыл написан так, чтобы по умолчанию принимать имена файлов, разделенные новой строкой -, вместо пробелов, но это разглагольствования для другого дня.)

0
25.08.2020, 19:07
1 ответ

В bash достаточно одного набора двойных -кавычек вокруг всего этого:

$ cat script
echo "my_cmd --attr1 $(($1-$2)) --attr2 $(($1-$2+$3)) --attr3 $(($2+1))"
$./script 20 10 10
my_cmd --attr1 10 --attr2 20 --attr3 11

Двойные кавычки разрешают замену на $, одинарные -кавычки рассматривают их как литералы.

1
18.03.2021, 23:10

Теги

Похожие вопросы