Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Background: I am working in Automator on a wrapper to a command line utility. I need a way to separate an arbitrary number of file paths delimited by a single space from a single string, so that I may remove all but the first file path to pass to the program.

Example input string:

/Users/bobby/diddy dum/ding.mp4 /Users/jimmy/gone mia/come back jimmy.mp3 ...

Desired output:

/Users/bobby/diddy dum/ding.mp4

Part of the problem is the inflexibility on the Automator end of things. I'm using an Automator action which returns unescaped POSIX filepaths delimited by a space (or comma). This is unfortunate because: 1. I cannot ensure file/folder names will not contain either a space or comma, and 2. the only inadmissible character in Mac OS X filenames (as far as I can tell) is :. There are options which allow me to enclose the file paths in double or single quotes, or angle brackets. The program itself accepts the argument of the aforementioned input string, so there must be a way of separating the paths. I just do not have a keen enough eye to see how to do it with sed or awk.

At first I thought I'll just use sed to replace every [space]/ with [newline]/ and then trim all but the first line, but that leaves the loophole open for folders whose names end with a space. If I use the comma delimiter, the same happens, just for a comma instead. If I encapsulate in double or single quotation marks, I am opening another can of worms for filenames with those characters.

The image/link is the relevant part of my Automator workflow.

-- UPDATE --

I was able to achieve what I wanted in a rather roundabout way. It's hardly elegant but here is working generalized code:

path="/Users/bobby/diddy dum/ding.mp4 /Users/jimmy/gone mia/come back jimmy.mp3"

# using colon because it's an inadmissible Mac OS X
# filename character, perfect for separating
# also, unlike [space], multiple colons do not collapse
IFS=:

# replace all spaces with colons
colpath=$(echo "$path" | sed 's/ /:/g')

# place words from colon-ized file path into array
# e.g. three spaces -> three colons -> two empty words
j=1
for word in $colpath
do
    filearray[$j]="$word"
    j=$j+1
done

# reconstruct file path word by word
# after each addition, check file existence
# if non-existent, re-add lost [space] and continue until found
name=""
for seg in "${filearray[@]}"
do
    name="$name$seg"
        if [[ -f "$name" ]]
        then
            echo "$name"
            break
        fi
    name="$name "
done

All this trouble because the default IFS doesn't count "emptiness" between the spaces as words, but rather collapses them all.

share|improve this question
    
Please post your solution as an answer - which you will be able to accept in a day or so. –  ChrisF Sep 18 '12 at 21:42
add comment

1 Answer

This shell code will concatenate segments of the input until they form a valid file (path) name:

file=""
sep=""
for word in $path
do
    file="$file$sep$word"
    if [[ -f "$file" ]]
    then
        break
    fi
    sep=" "
done
echo "first file: '$file'"

This assumes that the named files already exist (and your script can "see" them; i.e., can search the directories they are in) and it will still fail if a name contains multiple consecutive spaces (e.g., "diddy dum" is OK, but "diddy  dum" is not).

share|improve this answer
    
Thanks, I didn't think to split it by words in the shell. The only thing I will try to fix is the limitation on multiple spaces, but I think I'll do that in a roundabout way by first replacing spaces with colons in the string, settings IFS to colon, and then it will leave empty words (unlike for spaces which collapse) which I can turn back to spaces when I pass the string as an argument. –  user1130637 Sep 18 '12 at 18:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.