4

I've got a file called Files.txt having following content:

TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files/AppDelegate.m

I am pulling file and directory names as following and passing them to another process.

files=$(cat Files.txt)

for item in $files ; do    
  dn=$(dirname $item)

  printf $item
  printf "\n"
  printf $dn
  printf "\n\n"

  # passing to another process
done

However, this is getting me this:

TestApp/Resources/Supporting
TestApp/Resources

Files/main.m
Files

TestApp/Resources/Supporting
TestApp/Resources

Files/AppDelegate.h
Files

TestApp/Resources/Supporting
TestApp/Resources

Files/AppDelegate.m
Files

What I need is this:

TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.m
TestApp/Resources/Supporting Files

I tried prefixing space with \ in Files.txt as:

TestApp/Resources/Supporting\ Files/main.m

and with %20 as:

TestApp/Resources/Supporting%20Files/main.m

with no luck!

2 Answers 2

6
  1. for loops iterate over words not lines
  2. always quote your "$variables" (unless you know exactly when not to)
while read -r item ; do    
  dn=$(dirname "$item")

  printf "%s\n" "$item"
  printf "%s\n" "$dn"

  # pass "$item" and "$dn" to another process
done < Files.txt
2
  • Thanks but it seem to complain at the last line: dofiles.sh: line 9: syntax error near unexpected token done' dofiles.sh: line 9: ` done < Files.txt'` Commented Mar 28, 2014 at 20:20
  • Oops, missed the semicolon before "do" Commented Mar 28, 2014 at 20:21
1

You need to set the field separator:

OIFS=$IFS  
IFS=$'\n'

files=$(cat Files.txt)

for item in $files ; do    
  dn=$(dirname $item)
  printf $item
  printf "\n"
  printf $dn
  printf "\n\n"

  # passing to another process
done

IFS=$OIFS

Output:

[me@localhost test]$ ./test.sh 
TestApp/Resources/Supporting Files/main.m
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.h
TestApp/Resources/Supporting Files

TestApp/Resources/Supporting Files/AppDelegate.m
TestApp/Resources/Supporting Files

Explanation: http://en.wikipedia.org/wiki/Internal_field_separator

The $IFS variable defines how input is split into tokens, and the default is space, tab, and newline. Since you want to split only on newlines, the $IFS variable needs to be temporarily changed.

1
  • +1 - This works too. I picked the first answer, but up voted you - thanks! Commented Mar 28, 2014 at 20:25

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.