From 3e4999a18917fd2a49cecbcfdec98c7879b316a0 Mon Sep 17 00:00:00 2001 From: Felix Fischer Date: Tue, 25 Aug 2026 16:30:00 +0000 Subject: [PATCH] find: support %h format specifier in -printf Add support for the %h format specifier to find -printf, printing the leading directories of the path (equivalent to dirname). --- tests/find.test | 4 ++-- toys/posix/find.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/find.test b/tests/find.test index e4a161c4..7b7ce2d2 100755 --- a/tests/find.test +++ b/tests/find.test @@ -103,8 +103,8 @@ testing "-path glob" "find dir -path 'dir*e'" "dir/file\n" "" "" testing "-wholename glob" "find dir -wholename 'dir*e'" "dir/file\n" "" "" testing "-ipath glob" "find dir -ipath 'dIr*E'" "dir/file\n" "" "" testing "-iwholename glob" "find dir -iwholename 'dIr*E'" "dir/file\n" "" "" -testing "-printf" "find dir -name file -printf '%f %p %P %s'" \ - "file dir/file file 0" "" "" +testing "-printf" "find dir -name file -printf '%f %h %p %P %s'" \ + "file dir dir/file file 0" "" "" testing "-printf .N" "find dir -name file -printf %.2f" "fi" "" "" # findutils find supports C letter escapes and \0 octal, but not \x or \u. testing "-printf escapes" \ diff --git a/toys/posix/find.c b/toys/posix/find.c index ac148816..1b9aa645 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -59,9 +59,10 @@ config FIND -printf FORMAT characters are \ escapes and: %b 512 byte blocks used %f basename %g textual gid %G numeric gid - %i decimal inode %l target of symlink %m octal mode - %M ls format type/mode %p path to file %P path to file minus DIR - %s size in bytes %T@ mod time as unixtime + %h leading directories %i decimal inode %l target of symlink + %m octal mode %M ls format type/mode %p path to file + %P path to file minus DIR %s size in bytes + %T@ mod time as unixtime %u username %U numeric uid %Z security context */ @@ -634,7 +635,10 @@ static int do_find(struct dirtree *new) else if (ch == 'f') ll = (long)new->name; else if (ch == 'g') ll = (long)getgroupname(new->st.st_gid); else if (ch == 'u') ll = (long)getusername(new->st.st_uid); - else if (ch == 'l') { + else if (ch == 'h') { + ff = dirtree_path(new, 0); + ll = (long)dirname(ff); + } else if (ch == 'l') { ll = (long)(ff = xreadlinkat(dirtree_parentfd(new), new->name)); if (!ll) ll = (long)""; } else if (ch == 'M') { -- 2.39.5