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