Как выводить одинарные кавычки из оболочки в find exec - PullRequest
0 голосов
/ 08 мая 2020

РЕДАКТИРОВАТЬ

Между следующими ответами, chepner и Walter_A решают проблему. Вкратце, чтобы напечатать одинарную кавычку из команды find, вы

(1) используете "\ 047" вместо одинарной кавычки или

(2) определить локальную переменную, например, q = "'" непосредственно перед командой find и использовать $ q вместо знака одинарной кавычки.

Следовательно, решение этой проблемы specifici c не в использовании printf вместо echo или a для l oop вместо find ... exe c, но и printf, и for могут помочь улучшить код.


ОРИГИНАЛЬНЫЙ ВОПРОС:

Я пытаюсь автоматизировать следующий процесс:

  1. найти определенные файлы в текущем каталоге;

  2. добавить строку в текстовый файл для каждого имени файла, где имени файла предшествует строка «файл» и заключен в одинарные кавычки.

Фактически это упрощенная версия задачи: файлы, которые я ищу, являются видеофайлами, а ffmpeg делает некоторые работают над ними, прежде чем пытаться записать их имена в текстовый файл. Текстовый файл предназначен для последующего объединения выходных файлов. Полная строка такова:

    find . -maxdepth 1 -iname "name*" -exec sh -c 'ffmpeg -i "$0" -ss 3.3 -c:v libx264 -crf 20 -pix_fmt yuv420p -c:a copy "out/""$0"; echo "file ""\'""$(basename -- "$0")">>mylist.txt' {} \;

Однако видео часть работает хорошо, и я бы просто сосредоточился на печати одинарной кавычки (на экране или в файле), что доставляет мне проблемы. Если я попробую это:

      find . -iname "*" -exec sh -c 'echo "file ""$0"' {} \;

, я получу, как и ожидалось:

       file a1.mp4
       file a2.mp4
       [...]

Теперь я добавляю одинарную кавычку перед именем файла $ 0; между двойными или одинарными кавычками, с экранированием или без (если экранировал, я также пробовал это без кавычек), между кавычками после знака доллара, но все, что я получаю, это символ «>», за которым следует мигающий курсор, ожидающий ввода дополнительных данных.

Я попытался вставить одинарную кавычку как: "\ '",' \ '', \ ', $' '', $ '\' ', $ "\'"; Я поместил его в строку «файл» с одинарными или двойными кавычками и без них; Я установил переменную v = "file" "\ '" "$ 0" в exe c и ввел it в двойные кавычки. Однако все мои попытки провалились. Было бы хорошо понять почему. Возможно, здесь есть чему поучиться ... Спасибо за совет, который вы могли бы дать.

______________ РЕШЕНИЕ _______________

Я нашел обходной путь. Я пишу файл bash вместо того, чтобы давать одну команду из Терминала. Перед строкой поиска я экспортирую переменную SQ = "'". Тогда моя строка поиска становится:

    find . -maxdepth 1 -iname "*" -exec sh -c 'echo "file ""$SQ""$(basename -- "$0")""$SQ"' {} \;

И это работает. Возможно, одинарные кавычки, встречающиеся в экспортируемой переменной, не обрабатываются так же, как одинарные кавычки, встречающиеся в строках внутри оболочки или в локальных переменных?

Ответы [ 4 ]

1 голос
/ 08 мая 2020

Используйте printf вместо echo.

find . -iname "*" -exec printf "file '%s'" {} \;

Чтобы избежать разветвления внешнего printf для каждого файла, используйте sh, чтобы получить доступ к встроенной оболочке, используйте

find . -iname "*" -exec sh -c 'for f; do printf "file \047%s\047\n" "$f"; done' sh {} +

l oop в оболочке и терминатор + гарантируют, что sh будет выполняться как можно меньше раз. Проблемы с цитированием можно избежать, используя \047, чтобы указать printf выводить одинарную кавычку.


Обновление: я бы заменил find простой оболочкой l oop.

for full in name*; do
    f=$(basename "$full")
    ffmpeg -i "$full" -ss 3.3 -c:v libx264 -crf 20 -pix_fmt yuv420p -c:a copy "out/$f"
    printf "file '%s'\n" "$f" >> mylist.txt
done 
0 голосов
/ 08 мая 2020

Назначьте кавычку временной переменной (я также удаляю путь).

q="'" find . -iname "*" -exec sh -c 'echo "file $q${0##*/}$q"' {} \;
0 голосов
/ 08 мая 2020

Чтобы вставить одинарную кавычку внутри пары одинарных кавычек, используйте '"'"':

find . -maxdepth 1 -iname "*" -exec sh -c 'echo "file '"'"'$(basename -- "$0")'"'"'"' {} \;

Объяснение '"'"':

Первая ' закрывает предыдущую одинарную кавычку

"'" вставляет одинарную кавычку

Last ' перезапуск строки в одинарных кавычках.

0 голосов
/ 08 мая 2020

Разве эта строка не делает то же самое?

find . -iname "*" -exec sh -c 'echo "file" "$(basename $0)"' {} \;
...