3

I'm trying to write a script that does something a bit more sophisticated than what I'm going to show you, but I know that the problem is in this part.

I want each name of a list of files in a directory to be assigned to a variable (the same variable, one at a time) through a for loop, then do something inside of the loop with this, see what mean:

for thing in $(ls $1);
do
    file $thing;
done

Edit: let's say this scrypt is called Scrypt and I have a folder named Folder, and it has 3 files inside named A,B,C. I want it to show me on the terminal when I write this:

./scrypt Folder

the following:

A: file
B: file
C: file

With the code I've shown above, I get this:

A: ERROR: cannot open `A' (No such file or directory)
B: ERROR: cannot open `B' (No such file or directory)
C: ERROR: cannot open `C' (No such file or directory)

that is the problem

Zasito
  • 281
  • 1
  • 7
  • 17

4 Answers4

3

One way is to use wildcard expansion instead of ls, e.g.,

for filename in "$1"/*; do
    command "$filename"
done

This assumes that $1 is the path to a directory with files in it.

If you want to only operate on plain files, add a check right after do along the lines of:

[ ! -f "$filename" ] && continue
Arkku
  • 41,011
  • 10
  • 62
  • 84
  • The best way, assuming each `$1` is a folder. – Kevin Nov 22 '12 at 20:19
  • that would assing the directory name to filename, I need to give the name of the files inside the directory to filename. – Zasito Nov 22 '12 at 20:21
  • @Zasito: No, this would assign in turn the entire path to the files in that directory. If you need only the filename, you can use `basename "$filename"` to extract just the filename without the path. – Arkku Nov 22 '12 at 20:24
  • @Arkku: If i replace this on the thing I wrote on the question it will show me on the terminal this: $1: directory. Let's say that we put folder as the Argument, and it has inside 3 files A, B, C. When i write ./scrypt folder I want it to show A:file B:file C:file, if i put this, it will show only folder: directory. – Zasito Nov 22 '12 at 20:26
  • @Zasito: Did you copypaste the code exactly as shown, including quotes and the `/*` directly attached to the quote after `$1`? Also, do you have some other code in the script first, or did you test it with nothing but the code shown in my answer (with `command` replaced by `echo` or `file`)? – Arkku Nov 22 '12 at 20:38
  • waw! I assumed the /* was something else (starting in shell, I only know c++), so omitted it! Sorry! – Zasito Nov 22 '12 at 20:47
3

http://mywiki.wooledge.org/ParsingLs

Use globbing instead:

for filename in "$1"/* ; do
    <cmd> "$filename"
done

Note the quotes around $filename

Master Chief
  • 211
  • 1
  • 4
0

It's a bit unclear what you are trying to accomplish, but you can essentially do the same thing with functionality that already exists with find. For example, the following prints the contents of each file found in a folder:

find FolderName -type f -maxdepth 1 -exec cat {} \;
sampson-chen
  • 45,805
  • 12
  • 84
  • 81
0

well, i think that what you meant is that the loop will show the filenames in the desired dir. so, i would do it like that:

for filename in "$1"/*; do
echo "file: $filename"
done

that way the result should be (in case in the dir are 3 files and the names are A B C:

`file: A
`file: B
`file: C