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'`
    – Yas T.
    Mar 28, 2014 at 20:20
  • Oops, missed the semicolon before "do" 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!
    – Yas T.
    Mar 28, 2014 at 20:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .