Monday, January 15, 2024

Windows: no easy way to view a list of arbitrary file paths

problem: You have a list of arbitrary file paths and no easy way to view them

Let's say you're doing a file search on a cifs/smb share to find files with certain attributes or naming patterns.

You'd like to be able to view or preview the the file paths efficiently one by one, but the file paths are arbitrary. This means:

  1. The files are not all in the same directory.
  2. Some files may be in the same directory AND we want to ignore other files in such a case.

impact: this makes viewing the files difficult

Windows does not have native functionality to support viewing such a list of files.

solution: make a loop with cygstart

Cygwin can help here with its cygstart command.

# define pause function
function pause() { read -n1 -p"$@" </dev/tty; }
# export pause function
export -f pause

while IFS= read -r line; do printf "%q\n" "$line"; done < ../path/to/list_of_file_paths.txt | tr \\n \\0| xargs -I{} -0 -n1 -- sh -c 'echo "$1"; pause "press any key to cygstart the file, or CTRL+C to abort"; cygstart "$1"' cygstart_loop {}

# 💡 the .txt file is expected to contain file paths one per line, if some file paths contain a line break this logic needs to be updated to handle such a scenario.

# 👆 breakdown on the above loop
# 1. read the input .txt file line by line - expects file paths one per line

# 2. prints lines with %q format, which makes the output safe/escaped for shell input

# 3. translates newlines to zero/null bytes - assumes that no filename contains a newline
note: this may not be strictly necessary because we have used %q format BUT it does
explicitly document that we are working with records separated by new lines,
converting the new lines to zero/null bytes, and xargs is running in -0 mode.
xargs -0 removes any ambiguity in the record separator and mitigates file path special characters causing interpretation issues.

# 4. use xargs to run a simple sh script to prompt the user if they would like to cygstart the given file.
the user is shown the interpreted file path with the chance to abort.
  if the user does not abort - cygstart will attempt to open the file path using the file types default program for the file type.
note: this method should be mitigate command injection exploits, see: https://unix.stackexchange.com/a/156010/19406
note: cygstart_loop is the name of the ad-hoc sh script

citation:

Props to:
Stéphane Chazelas @ Stack Exchange / Unix & Linux / their detailed answer on using shell input safely.