bash 如何在shell脚本中获取目录中的文件列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2437452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:02:33  来源:igfitidea点击:

How to get the list of files in a directory in a shell script?

bashshelldirectory-listing

提问by jrharshath

I'm trying to get the contents of a directory using shell script.

我正在尝试使用 shell 脚本获取目录的内容。

My script is:

我的脚本是:

for entry in `ls $search_dir`; do
    echo $entry
done

where $search_diris a relative path. However, $search_dircontains many files with whitespaces in their names. In that case, this script does not run as expected.

哪里$search_dir是相对路径。但是,$search_dir包含许多名称中带有空格的文件。在这种情况下,此脚本不会按预期运行。

I know I could use for entry in *, but that would only work for my current directory.

我知道我可以使用for entry in *,但这仅适用于我当前的目录。

I know I can change to that directory, use for entry in *then change back, but my particular situation prevents me from doing that.

我知道我可以更改到该目录,使用for entry in *然后更改回来,但我的特殊情况阻止我这样做。

I have two relative paths $search_dirand $work_dir, and I have to work on both simultaneously, reading them creating/deleting files in them etc.

我有两个相对路径$search_dir$work_dir,我必须同时处理这两个路径,读取它们在其中创建/删除文件等。

So what do I do now?

那我现在该怎么办?

PS: I use bash.

PS:我使用 bash。

回答by Ignacio Vazquez-Abrams

for entry in "$search_dir"/*
do
  echo "$entry"
done

回答by tegan

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:

此处的其他答案很好,可以回答您的问题,但这是“bash 获取目录中的文件列表”的最佳谷歌结果(我一直在寻找保存文件列表),所以我想我会发布一个这个问题的答案:

ls $search_path > filename.txt

If you want only a certain type (e.g. any .txt files):

如果您只需要某种类型(例如任何 .txt 文件):

ls $search_path | grep *.txt > filename.txt

Note that $search_path is optional; ls > filename.txt will do the current directory.

请注意,$search_path 是可选的;ls > filename.txt 将执行当前目录。

回答by rrr

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
*.txtreturns anything.txt
You can check what will be listed easily by typing the lscommand straight into the terminal.

./是当前工作目录,但可以替换为任何路径
*.txt返回任何内容.txt
您可以通过ls直接在终端中键入命令来轻松检查将列出的内容。

Basically, you create a variable yourfilenamescontaining everything the list command returns as a separate element, and then you loop through it. The loop creates a temporary variable eachfilethat 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 lscommand and the for loop syntax.

基本上,您创建一个变量,yourfilenames其中包含 list 命令作为单独元素返回的所有内容,然后循环遍历它。循环创建一个临时变量eachfile,其中包含它循环通过的变量的单个元素,在本例中为文件名。这不一定比其他答案更好,但我觉得它很直观,因为我已经熟悉ls命令和 for 循环语法。

回答by ghostdog74

for entry in "$search_dir"/* "$work_dir"/*
do
  if [ -f "$entry" ];then
    echo "$entry"
  fi
done

回答by Noel Yap

find "${search_dir}" "${work_dir}" -mindepth 1 -maxdepth 1 -type f -print0 | xargs -0 -I {} echo "{}"

回答by Victoria Stuart

$ 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 1to 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
  • .: 当前文件夹
  • 删除-maxdepth 1以递归搜索
  • -type f: 查找文件,而不是目录 ( d)
  • -not -path '*/\.*': 不回 .hidden_files
  • sed 's/^\.\///g':./从结果列表中删除前置

回答by Michael Sisko

Just enter this simple command:

只需输入这个简单的命令:

ls -d */

回答by SnoopDogg

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 forloop iterates over each file name and prints to stdout.

echo *输出当前目录的所有文件。该for循环遍历每个文件名,并打印到标准输出。

Additionally, If looking for directories inside the directory then place this inside the forloop:

此外,如果在目录中查找目录,则将其放入for循环中:

if [ test -d $z ]; then
    echo "$z is a directory"
fi

test -dchecks if the file is a directory.

test -d检查文件是否为目录。

回答by TrevTheDev

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

回答by Andrushenko Alexander

On the Linux version I work with (x86_64 GNU/Linux) following works:

在我使用的 Linux 版本 (x86_64 GNU/Linux) 上,以下工作:

for entry in "$search_dir"/*
do
  echo "$entry"
done