Let's suppose that you need to generate a NUL
-delimited stream of timestamped filenames.
On Linux & Solaris I can do it with:
stat --printf '%.9Y %n\0' -- *
On BSD, I can get the same info, albeit delimited by newlines, with:
stat -f '%.9Fm %N' -- *
The man
talks about a few escape sequences but the NUL
byte doesn't seem supported:
If the
%
is immediately followed by one ofn
,t
,%
, or@
, then anewline
character, atab
character, apercent
character, or the current file number is printed.
Is there a way to work around that?
CodePudding user response:
Unfortunately, stat
out of the box does not offer this option, and so what you ask is not directly achievable.
However, you can easily implement the required functionality in a scripting language like Perl or Python.
#!/usr/bin/env python3
from pathlib import Path
from sys import argv
for arg in argv[1:]:
print(
Path(arg).stat().st_mtime,
arg, end="\0")
Demo: https://ideone.com/vXiSPY
The demo exhibits a small discrepancy in the mtime which does not seem to be a rounding error, but the result could be different on MacOS (the demo platform is Debian Linux, apparently). If you want to force the result to a particular number of decimal places, Python has formatting facilities similar to those of stat
and printf
.
CodePudding user response:
With any command that can't produce NUL-terminated output, you can just wrap it in a function to call the command and then printf
it's output with a terminating NUL instead of newline:
nulstat() {
local fmt=$1 file
shift
for file in "$@"; do
printf '%s\0' "$(stat -f "$fmt" "$file")"
done
}
nulstat '%.9Fm %N' *
For example:
$ > foo
$ > $'foo\nbar'
$ nulstat '%.9Fm %N' foo* | od -c
0000000 1 6 6 3 1 6 2 5 3 6 . 4 7 7 9 8
0000020 0 1 4 0 f o o \0 1 6 6 3 1 6 2
0000040 5 3 9 . 3 8 8 0 6 9 9 3 0 f o
0000060 o \n b a r \0
0000066
CodePudding user response:
Is there a way to work around that?
If all you need is to just replace all newlines with NULLs, then following tr
should suffice
stat -f '%.9Fm %N' * | tr '\n' '\000'
Explanation: 000
is NULL
expressed as octal value.