Listing files in another directory
Posted by: Mark Bools on 2020-02-19 The other day I was editing a YAML file and wanted to include a list of filenames from a directory other than the current working directory. A simple Two solutions spring to mind: Getting these directly into the file I was editing was simple enough. I was using The first solution pipes the output of the The shortcoming of this solution being that if the The second solution is, I think, more elegant and will not fall foul of command line length limitations. The parentheses tell the The Problem
ls does not do what I intended as it will recurse the remote directory listing all files and directories and, as it happened, the ‘files’ I wanted to list were actually directories (FYI, they were screenflow captures that MacOS helpfully presents as if they are files but are in fact composite directories). Since a simple ls yields undesired output I needed another solution.Solution
ls -d ../raw/screenflow/20200218* | xargs basename(cd ../raw/screenflow && ls -d1 20200218*)vim so a simple :r!<command> read the output of the <command> straight into the buffer.Discussion
Solution 1
ls command into the basename command (using xargs to feed the ls output onto the command line as parameter). In its raw form the ls -d command lists matching files but (importantly for this application) does not recurse into directories. So far, so good, the output from this command does however list the full matching path. The basename is used to extract the last element of the path, specifically the Screenflow directory names.1
2
3
4
5
6
7
8
$ ls -d ../raw.screenflow/20200218*
../raw/screenflow/202002181358.screenflow ../raw/screenflow/202002181429.screenflow ../raw/screenflow/202002181432.screenflow ../raw/screenflow/202002181435.screenflow
$ ls -d ../raw/screenflow/20200218* | xargs basename
202002181358.screenflow
202002181429.screenflow
202002181432.screenflow
202002181435.screenflow
ls output is long (many matching paths or long paths) the xargs basename may break with the ‘argument list too long’ error. That said, the command line limit is usually very long (typically several thousand characters, check with getconf ARG_MAX).Solution 2
bash shell to create a new subprocess in which the enclosed commands will be run. Using the subprocess means that any side-effects of the commands (for example changing the current directory with cd) will not effect our current session.ls -d1 tells the ls command to ‘not recurse into directories’ (-d) and the list one entry per line ('-1), rather than space separated on the line. As we changed our working directory to the target directory the paths contain only the matching file/directory names, exactly what we want.1
2
3
4
5
$ (cd ../raw/screenflow && ls -d1 20200218*)
202002181358.screenflow
202002181429.screenflow
202002181432.screenflow
202002181435.screenflow