2

As simple and naïve as it sounds, I'm struggling with the find and file command. I use -exec file because the specific files I need to obtain do not have their extension name in the filename, which eliminates the possiblity of the -name option in find. See my find command and workspace below:

My Current Code:

workspace=/PATH/
### --- Example hierarchy of where all the files needed are located recursively:
##### -----("$workspace"/ID/ID/DICOM/cat)
####### ------- 'cat' is a .dcm file, without ".dcm" in its name

PETS=`find . -type f -exec file {} \; | grep "DICOM"`

My current output, which looks like a typical output for find:

./PATH/ID/ID/DICOM/cat: DICOM medical imaging data (1)

By default, I would've done this to assign it to a variable:

PETS=($(find . -type f -exec file {} \; | grep "DICOM"))

However, I only get the first instance through this output (when there are many other DICOM files located in relation to the working directory), which almost is a truncated version of my current output above in (1)

./PATH/ID/ID/DICOM/cat: (2)

How do I actually obtain the files themselves from (1) or (2), or from a modification of my find command, so I can feed it into the dcmdump utility from the dctmk Toolbox?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
florence-y
  • 751
  • 3
  • 8
  • 18
  • 1
    dcmdump supports recursively searching a directory for files. When called with option +fo (--read-file-only) you could also make sure that only DICOM files are actually processed (i.e. parsed) by this tool. – J. Riesmeier Sep 25 '19 at 11:20

1 Answers1

1

The syntax is a bit hairy, but if you can call both file and grep from within the -exec action then you can continue chaining additional actions without needing any intermediate variables.

The way to do it is to create an explicit sub-shell that contains the file | grep pipeline: sh -c 'file "$1" | grep -q DICOM'. "$1" is a placeholder for the file being checked since that's how shell scripts take arguments. (It's not a good idea to embed {} inside the script. We'd have issues with special characters like spaces and quotes.)

So how do we set $1? The answer by appending arguments to the shell command: sh -c '<script>' arg0 arg1 arg2... sets the positional arguments $0, $1, $2, etc., to the strings arg0, arg1, arg2, and so on. Let's do that. We can set $0 to sh, the name of the shell; and $1 to {}, the file name from find.

This whole -exec action can be treated as a test that passes or fails, no different from a simpler test like -type f. We can chain other conditional actions such as a call to dcmdump.

All together we get:

find . -type f -exec sh -c 'file "$1" | grep -q DICOM' sh {} \; -exec dcmdump {} +
John Kugelman
  • 349,597
  • 67
  • 533
  • 578