Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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!

share|improve this question

2 Answers 2

up vote 6 down vote accepted
  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
share|improve this answer
    
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 Kuraishi Mar 28 at 20:20
    
Oops, missed the semicolon before "do" –  glenn jackman Mar 28 at 20:21
    
Yup, works. Thanks! –  Yas Kuraishi Mar 28 at 20:23

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.

share|improve this answer
    
+1 - This works too. I picked the first answer, but up voted you - thanks! –  Yas Kuraishi Mar 28 at 20:25

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.