p Команды ipe внутри find -exec?

Вы создали переменную с именем _now, но позже ссылаетесь на переменную с именем _nowout. Чтобы избежать подобных проблем, используйте фигурные скобки для разделения имен переменных:

_now=$(date +"%m_%d_%Y")
_file="${_now}out.log"
touch "$_file.txt"

Обратите внимание, что я оставил "$_file.txt" как есть, потому что . уже является разделителем имен переменных. Если есть сомнения, можно использовать "${_файл}.txt".

Бонус 1: ${varname} синтаксис на самом деле обеспечивает несколько полезных строковых операций над переменными, в дополнение к разграничению.

Бонус 2: для разграничения имен переменных можно также использовать творческое экранирование и кавычки оболочки. Можно заключить в кавычки переменную и строковый литерал отдельно (например, file="$_now""out.log" или file="$_now"'out.log') или оставить одну из частей без кавычек (например, file=$_now "out.log" или file="$_now "out.log). Наконец, вы можете экранировать один символ, который следует за именем переменной: file=$_now\out.log. Хотя я бы не рекомендовал повторно использовать эти примеры без хорошего понимания правил цитирования и экранирования shell.

4
18.03.2019, 18:43
2 ответа

Если вы должны сделать это из find, вам нужно вызвать оболочку:

find./ -type f -name "*.txt" -exec sh -c 'grep -EiH something "$1" | grep -E somethingelse | grep -E other' sh {} \;

Другие альтернативы включают использование xargsвместо:

find./ -type f -name "*.txt" | 
    xargs -I{} grep -EiH something {} | 
        grep -EiH somethingelse | 
            grep -EiH other

Или, что намного безопаснее для произвольных имен файлов (, если ваш findподдерживает-print0):

find./ -type f -name "*.txt" -print0 | 
    xargs -0 grep -EiH something {} | 
        grep -Ei somethingelse | 
            grep -Ei other

Или вместо этого вы можете просто использовать цикл оболочки:

find./ -type f -name "*.txt" -print0 | 
    while IFS= read -d '' file; do 
        grep -Ei something "$file" | 
            grep -Ei somethingelse | 
                grep -Ei other
    done
15
27.01.2020, 20:47

Изменить :Этот ответ не предпочтителен , но оставлен здесь для сравнения и иллюстрации потенциально опасных ловушек в сценариях bash.


Вы можете указатьbash(или другую оболочку )в качестве команды -exec:

find -type -f -name "*.txt" -exec bash -c 'egrep -iH something "{}" | egrep somethingelse | egrep other' \;

Одним из недостатков этого способа является то, что он создает больше возможностей для проблем с вложенными кавычками по мере того, как ваши команды становятся более сложными. Если вы хотите избежать этого, вы можете разбить его на циклfor-:

for i in $(find -type -f -name "*.txt"); do
  if egrep -iH something "$i" | egrep somethingelse | egrep other; then 
    echo "Found something: $i"
  fi
done
2
27.01.2020, 20:47

Теги

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