The stat command from GNU core utilities features not only a --format FORMAT option but also a --printf FORMAT one, the difference being that the latter allows for backslash escapes such as \n.
This allows for custom per-file report formats containing newlines, for example:
stat --printf 'Name: %n\nSize: %s Bytes\n' /etc/passwd
If the format string becomes more complex, the command line soon becomes unwieldy, such as:
stat --printf 'Name: %n\nOwner ID: %u\nSize: %s Bytes\nLast accessed: %x\n' /etc/passwd
Using a multi-line string, the format string can be broken up, but continuation and indentation rules make it difficult to maintain a neat organization to the format text. An example follows (there is also a variant that uses line continuation, but it suffers from similar problems):
stat --printf \
'Name: %n
Owner ID: %u
Size: %s Bytes
Last accessed: %x
' /etc/passwd
Let’s write down the lines of the report format for stat as a Bourne Again Shell array, one element per line:
STAT_FMT=(
"Name: %n"
"Owner ID: %u"
"Size: %s Bytes"
"Last accessed: %x"
)
Now we need an expression that expands this data structure into a single argument for stat, interleaving the elements with line-breaks.
The following attempt uses the special variable IFS and the single-word array expansion:
# Problematic: Only the first character of IFS actually applies.
IFS='\n' ; stat --printf "${STAT_FMT[*]}" /etc/passwd
This leads to errors like this:
stat: warning: unrecognized escape '\O'
IFS needs to be a single character, and the escape sequence \n is two characters long; assigning \n to IFS will result in only the first character, \ being interleaved.
This is one of the (rare) use cases for Bourne Again Shell’s ’single quote expansion‘ which takes the form $'\n' – it expands to a single-quoted string where backspace escape sequences have been expanded to their literal values – in the case of \n this would be the ASCII Line Feed (0xa), a single character.
The following works:
IFS=$'\n' ; stat --printf "${STAT_FMT[*]}" /etc/passwd
A more complete code example follows. Note that in this example the stat call with the modified IFS variable has been put into a function, with IFS being (re-)declared a local variable so that the IFS modification would not interfere with later commands.
STAT_FMT=(
"Information about file \"%n\":"
"- Owner ID: %u"
"- Size: %s Bytes"
"- Last accessed: %x"
"- Last modified: %y"
"- Last changed: %z"
)
stat_fmt() {
local IFS=$'\n'
stat --printf "${STAT_FMT[*]}\n" "$@"
}
stat_fmt /etc/passwd
- GNU find hat keine Option „-older“ …
- Bourne to Bourne Again Shell Forward Compatibility
- Print XDG Desktop Definition for Application
- Find Files by Size given in Bytes
- Using sed or awk to ensure a specific last Line in a Text
- Make a Bourne Again Shell Script Log its Output to a File
- Maintaining Multi-Line „stat“ Formats using Bourne Again Shell
- Print all indented Lines following a non-indented Line