цитаты внутри backticks внутри цитат в ksh

Я пытаюсь получить файл текущей даты со следующей командой в HP-UX Unix:

$ lt ABC.LOG* |grep "`date +"%b %d"`" 

Но это дает мне ошибку:

 ksh: : cannot execute grep: can't open %d 

Какие-либо предложения?

Ошибка связана с цитированием аргументов grep и тем фактом, что обратные ссылки не очень хорошо встраиваются:

 grep "`date +"%b %d"`" 

Это лучше написано как

 grep "`date +'%b %d'`" 

… или даже лучше,

 grep "$(date +'%b %d')" 

Фактически, с $(...) вместо backticks, вы должны иметь возможность сохранить внутренние двойные кавычки:

 grep "$(date +"%b %d")" 

Альтернативой grepping вывода ls было бы сделать

 find . -type f -name "ABC.LOG*" -ctime -1 

Это найдет все обычные файлы ( -type f ) в текущем каталоге, имена которых соответствуют заданному шаблону и время ctime которого меньше 24 часов с момента текущего времени . Время ctime файла – это время, когда была произведена последняя модификация данных или метаданных файла.

Это не совсем эквивалентно тому, что вы пытаетесь достичь. Это также повторяется в подкаталоги.

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

 echo "`date" 

работает и совпадает с:

 echo "`date`" echo "$(date)" 

А также:

 echo `echo "foo` 

работает и совпадает с:

 echo `echo "foo"` echo $(echo "foo") 

Если вы это сделаете:

 grep "`date +"%b %d"`" 

Это принято как слово grep а затем "`date +" (закрытые backticks внутри двойных кавычек), объединенные с %b а затем %d объединенные с другими незакрытыми обратными выводами внутри двойных кавычек: "`" . Так что это похоже на

 grep "$(date +)"%b %d"$()" 

(за исключением того, что по какой-то причине, в то время как echo "``" или echo "$()" не вызовет ошибку, в echo "`" , оболочка попытается выполнить команду с пустым именем (как если бы вы написали echo "$("")" ).

Итак, здесь вам нужно использовать обратную косую черту, чтобы помочь синтаксическому анализатору:

 grep "`date +\"%b %d\"`" 

Эти обратные косые черты фактически удаляются. Это date +"%b %d" , которая оценивается подселей в подстановке команд.

Здесь, поскольку ksh принимает закрытые кавычки, вы также можете:

 grep "`date +\"%b %d" 

(не то, что я бы посоветовал сделать это).

Вот как вы можете получить вложенные backticks как в:

 echo "`echo \"\`echo \\\"ab\\\"\`\"`" 

Хороший пример, почему никто вряд ли когда-либо использует этот синтаксис и использует $(...) более новую форму (введенную ksh в начале 80-х):

 echo "$(echo "$(echo "ab")")" 

Теперь, для вашей конкретной проблемы, похоже, что вы хотите перечислить файлы ABC.LOG* в текущем каталоге, который был последним изменен сегодня. Для этого вы можете:

 touch -t "$(date +%Y%m%d0000)" .start-of-day && find . ! -name . -prune -name 'ABC.LOG.*' \ -newer .start-of-day -type f -exec ls -lrtd {} + && rm -f .start-of-day 

Команда find может быть использована для правильного инструмента, вместо выполнения ls и grep ing result, поэтому хорошо заметить, что, пожалуйста , не анализируйте результат ls .

 find /path/to/ -type f -name "ABC.LOG*$(date +"%b %d")*" 

Вы ищете сегодняшнюю дату в имени файла , если вы ищете файлы, созданные / измененные в сегодняшнюю дату, вы можете использовать find как этот способ (версия find GNU):

 find /path/to -type f -name "ABC.LOG*" -newermt 00:00 

Или в последние 24 часа:

 find /path/to -type f -name "ABC.LOG*" -newermt yesterday 

Или как следует:

 find /path/to -type f -name "ABC.LOG*" -newermt "$(date +"%b %d")"