Home > Software design >  Pipe filename to ImageJ
Pipe filename to ImageJ

Time:11-25

I have a little command line utility rjp2tif that extracts radiometric data from a jpeg file into a tiff file. I was hoping to be able to pipe the filepath to ImageJ on the command line and have ImageJ open the tiff file. To this end, rjp2tif writes the filepath of the tiff file to standard output. I tried the following in bash:

$ rjp2tif /path/to/rjpeg | open -a imagej

and

$ rjp2tif /path/to/rjpeg | open -a imagej -f

The first opens ImageJ but doesn't open the file. The second opens ImageJ with a text window with the filepath in it.

This is on macOS Monterey, but I don't think that matters. Anyone tried to do this and been successful? TIA.

CodePudding user response:

Assuming the rjp2tif command returns a file-path in standard output, and you want to pass this output as a regular CLI argument to another command, you may be interested in the xargs command. But note that in the general case, you may hit some issue if the file-path contains spaces or so:

Read space, tab, newline and end-of-file delimited arguments from standard input and execute the specified utility with them as arguments.
The arguments are typically a long list of filenames (generated by ls or find, for example) that get passed to xargs via a pipe.

So in this case, assuming each file-path takes only one line (which is obviously the case if there's only one line overall), you can use the following NUL-based tip relying on the tr command.

Here is the command you'd obtain:

rjp2tif /path/to/rjpeg | tr '\n' '\0' | xargs -0 open -a imagej

Note: I have a GNU/Linux OS, so can you please confirm it does work under macOS?

FTR, below is a comprehensive shell code allowing one to test two different modes of xargs: generating one command per line-argument (-n1), or a single command with all line-arguments in one go:

$ printf 'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 \
  bash -c 'printf "Run "; for a; do printf "\"$a\" "; done; echo' bash
Run "one " 
Run "two" 
Run "three and four" 

$ printf 'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 \
  bash -c 'printf "Run "; for a; do printf "\"$a\" "; done; echo' bash
Run "one " "two" "three and four" 

######################################
# or alternatively (with no for loop):
######################################

$ printf 'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 \
  bash -c 'printf "Run "; printf "\"%s\" " "$@"; echo' bash
Run "one " 
Run "two" 
Run "three and four" 

$ printf 'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 \
  bash -c 'printf "Run "; printf "\"%s\" " "$@"; echo' bash
Run "one " "two" "three and four" 
  • Related