I'm trying to get the contents of a directory using shell script.
My script is:
for entry in `ls $search_dir`; do
echo $entry
done
where $search_dir
is a relative path. However, $search_dir
contains many files with whitespaces in their names. In that case, this script does not run as expected.
I know I could use for entry in *
, but that would only work for my current directory.
I know I can change to that directory, use for entry in *
then change back, but my particular situation prevents me from doing that.
I have two relative paths $search_dir
and $work_dir
, and I have to work on both simultaneously, reading them creating/deleting files in them etc.
So what do I do now?
PS: I use bash.
for entry in "$search_dir"/*
do
echo "$entry"
done
The other answers on here are great and answer your question, but this is the top google result for "bash get list of files in directory", (which I was looking for to save a list of files) so I thought I would post an answer to that problem:
ls $search_path > filename.txt
If you want only a certain type (e.g. any .txt files):
ls $search_path | grep *.txt > filename.txt
Note that $search_path is optional; ls > filename.txt will do the current directory.
for entry in "$search_dir"/* "$work_dir"/*
do
if [ -f "$entry" ];then
echo "$entry"
fi
done
This is a way to do it where the syntax is simpler for me to understand:
yourfilenames=`ls ./*.txt`
for eachfile in $yourfilenames
do
echo $eachfile
done
./
is the current working directory but could be replaced with any path*.txt
returns anything.txt
You can check what will be listed easily by typing the ls
command straight into the terminal.
Basically, you create a variable yourfilenames
containing everything the list command returns as a separate element, and then you loop through it. The loop creates a temporary variable eachfile
that contains a single element of the variable it's looping through, in this case a filename. This isn't necessarily better than the other answers, but I find it intuitive because I'm already familiar with the ls
command and the for loop syntax.
find "${search_dir}" "${work_dir}" -mindepth 1 -maxdepth 1 -type f -print0 | xargs -0 -I {} echo "{}"
$ pwd; ls -l
/home/victoria/test
total 12
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:31 a
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:31 b
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:31 c
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:32 'c d'
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:31 d
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32 dir_a
drwxr-xr-x 2 victoria victoria 4096 Apr 23 11:32 dir_b
-rw-r--r-- 1 victoria victoria 0 Apr 23 11:32 'e; f'
$ find . -type f
./c
./b
./a
./d
./c d
./e; f
$ find . -type f | sed 's/^\.\///g' | sort
a
b
c
c d
d
e; f
$ find . -type f | sed 's/^\.\///g' | sort > tmp
$ cat tmp
a
b
c
c d
d
e; f
Variations
$ pwd
/home/victoria
$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2
$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2
Notes:
.
: current folder- remove
-maxdepth 1
to search recursively -type f
: find files, not directories (d
)-not -path '*/\.*'
: do not return.hidden_files
sed 's/^\.\///g'
: remove the prepended./
from the result list
Here's another way of listing files inside a directory (using a different tool, not as efficient as some of the other answers).
cd "search_dir"
for [ z in `echo *` ]; do
echo "$z"
done
echo *
Outputs all files of the current directory. The for
loop iterates over each file name and prints to stdout.
Additionally, If looking for directories inside the directory then place this inside the for
loop:
if [ test -d $z ]; then
echo "$z is a directory"
fi
test -d
checks if the file is a directory.
The accepted answer will not return files prefix with a . To do that use
for entry in "$search_dir"/* "$search_dir"/.[!.]* "$search_dir"/..?*
do
echo "$entry"
done
On the Linux version I work with (x86_64 GNU/Linux) following works:
for entry in "$search_dir"/*
do
echo "$entry"
done
来源:https://stackoverflow.com/questions/2437452/how-to-get-the-list-of-files-in-a-directory-in-a-shell-script