#!/usr/bin/perl -w # # uniq_dirs # # AUTHOR: # Dan Harkless http://harkless.org/dan/software/ # # COPYRIGHT: # This file is Copyright (C) 2017 by Dan Harkless, and is released under the # GNU General Public License . # # USAGE: # % uniq_dirs [...] # # DESCRIPTION: # Takes a list of pathnames and outputs an alpha-sorted list of all the unique # directories that contain those files. The pathnames should be newline- # separated, and can be given on stdin, or can be specified inside one or more # input files given on the commandline. I wrote this because commandlines # like: # # % locate kill | xargs dirname | sort -u # # can misbehave if there are spaces and/or single quotes in filenames, while # commandlines like: # # % locate -0 kill | xargs -0 dirname | sort -u # # can potentially result in an "xargs: argument line too long" error. # # Note that this command is not spelled "unique_dirs", but "uniq_dirs", like # the standard UNIX utility "uniq". Also note that uniq_dirs does not check # to see that the named files actually exist in the given directories; # dirname() is simply used to differentiate directory from file. # # EXAMPLE: # % locate kill | uniq_dirs # /home/me/Documents/Lizzie B.'s stuff # /usr/bin # /usr/share/bash-completion/completions # /usr/share/man/man1 # /usr/share/man/man3 # /usr/share/vim/vim80/syntax # # TODO: # Add an option to output the files specified on input that are in each # directory, using "/some/dir/{file1,file2}" syntax? # # DATE MODIFICATION # ========== ================================================================== # 2017-04-18 Original. ## Modules used ################################################################ use English; # allow long English names like $ARG instead of $_ use File::Basename; # for dirname() ## Main ######################################################################## while (<>) { $dirs{dirname($ARG)} = 1; } foreach $dir (sort(keys(%dirs))) { print "$dir\n"; }