4

I'm trying to get the file of the current date with the following command in HP-UX Unix:

$ ls -lrt ABC.LOG* |grep "`date +"%b %d"`"

But, it's giving me the error:

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

Any suggestions?

7

The error stems from the quoting of the arguments of grep and the fact that backticks don't do nesting very well:

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

This is better written as

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

... or even better,

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

In fact, with $(...) instead of backticks, you should be able to keep the inner double quotes:

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

An alternative to grepping the output of ls would be to do

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

This would find all regular files (-type f) in the current directory whose names matches the given pattern and whose ctime is less than 24 hours since the current time. A file's ctime is the time when the last modification of the file's data or metadata was made.

This is not exactly equivalent to what you're trying to achieve though. This also recurses into subdirectories.

  • I'm actually parsing the date through ls -lrt, so grep "$(date +"%b %d")" or grep "date +'%b %d'" will do for me. – User123 Aug 20 '17 at 10:01
  • 1
    @Ashish don't parse ls result, + you will get this wrong result -rw-rw-rw- 1 USER USER 118 Jul 20 15:31 fileAug 20 – αғsнιη Aug 20 '17 at 11:49
  • @Kusalananda you could limit to current directory find . -maxdepth 1 ... – waltinator Aug 20 '17 at 18:32
  • @waltinator Not with the default find on HP-UX. – Kusalananda Aug 20 '17 at 20:59
4

In the Korn shell, like in the Bourne shell, quotes and backticks (the archaic form of command substitution) can be unmatched, and you have to help the tokeniser to tell where backticks end. Inside backticks there's another level of backslash processing.

echo "`date"

works and is the same as:

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

And:

echo `echo "foo`

works and is the same as:

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

If you do:

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

That's taken as a grep word and then "`date +" (unclosed backticks inside double quotes) concatenated with %b and then %d concatenated with another unclosed backticks inside double-quotes: "`". So it's like

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

(except that for some reason, while echo "``" or echo "$()" would not cause an error, in echo "`", the shell will try to execute a command with an empty name (as if you had written echo "$("")").

So here, you need to use backslash to help the parser:

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

Those backslashes are actually removed. It is date +"%b %d" that is being evaluated by the subshell in the command substitution.

Here, since ksh accepts unclosed quotes, you could actually also do:

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

(not that I would advise doing that).

That's also how you can get nested backticks as in:

echo "`echo \"\`echo \\\"a  b\\\"\`\"`"

A good example why nobody hardly ever uses that syntax and use the $(...) newer form (introduced by ksh in the early 80s):

echo "$(echo "$(echo "a  b")")"

Now, for your particular problem, it looks like you want to list ABC.LOG* files in the current directory that were last-modified today. For that, you could do:

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
4

The find command can be used for the correct tool, instead of doing ls and greping result, so it's good to note that please don't parse ls result.

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

Above is looking for today's date in filesname, if you are looking for the files created/modified in today's date, you could use find as this way (GNU version of find):

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

Or in last 24Hours:

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

Or as follow:

find /path/to -type f -name "ABC.LOG*" -newermt "$(date +"%b %d")"
  • Note that with -newermt yesterday, that's files last modified in the last 24 hours (except around DST changes), not the files last modified today. For that, you'd want -newermt 00:00 – Stéphane Chazelas Aug 20 '17 at 18:14
  • Also note that while -newerxy likely originated in HP/UX find, the variant where y == t is still not supported there AFAIK (added to FreeBSD first, now also supported by GNU). – Stéphane Chazelas Aug 20 '17 at 18:34
  • @StéphaneChazelas Thank you, I added this to answer – αғsнιη Aug 21 '17 at 3:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.