在Linux中如何生成带有文件绝对路径的列表?

414
我正在编写一个以文件路径为输入的shell脚本。
因此,我需要生成包含完整路径的递归文件列表。例如,文件bar的路径为:
/home/ken/foo/bar

但就我所见,无论是ls还是find都只提供相对路径的列表:

./foo/bar   (from the folder ken)

这似乎是一个显而易见的需求,但我在 findls 的帮助文档中找不到任何相关内容。

如何在 shell 中生成包含文件绝对路径的文件列表?


2
使用以下命令在Linux中查找文件并显示其详细信息:find /home/ken/foo/bar -exec ls -ld $PWD/{} \; - Learner
29个回答

405

如果你给find一个绝对路径作为起点,它会打印出绝对路径。例如,在当前目录中查找所有的 .htaccess 文件:

find "$(pwd)" -name .htaccess

或者如果你的 shell 将 $PWD 展开为当前目录:

find "$PWD" -name .htaccess

find 简单地将其给定的路径前置到相对于该路径的文件的路径中。

Greg Hewgill 还建议如果你想解析当前目录中的符号链接,可以使用 pwd -P


11
请注意,如果您想解析符号链接,请使用 pwd -P - Greg Hewgill
7
这很有帮助,但我认为下面user431529的回复更加可靠: ls -d -1 $PWD/**/* 不过我猜在bash中也可以用 find $PWD(已测试)。 - Brian
11
@Brian 为什么要用find $PWD呢?这很简单。相比之下,ls命令则复杂而难以掌握(除非你将其设置别名)。find命令不依赖于shell的通配符扩展,因此适用于任何shell。另外find更加灵活,可以递归地列出所有文件,或者只列出目录,或者列出所有XML文件,还可以列出在最近一周内修改过的所有文件。这些都是通过find命令实现的,但使用ls却不太容易。 - Matthew Scharley
13
由于目录名中包含空格,我不得不使用find "\pwd`" -name .htaccess`。 - Paulo Casaretto
@Bjørn:复制/粘贴?pwd输出什么?我只是用它作为一个例子,但只要你给find一个绝对路径,它就应该输出绝对路径。 - Matthew Scharley
显示剩余3条评论

254
readlink -f filename 

返回完整的绝对路径。但如果文件是符号链接,你将得到最终解析的名称。


9
好的。这段话是在说“Nice”这个命令在BSD变种的readlink上不能用,也就是在Mac系统上不能用。作者在Mac上使用了gnucoreutils,因此可以使用greadlink来运行上面的解决方案。 - sheki
3
在Mac OS X中,请使用“realpath”代替。 - c z
如果您通过brew install coreutils安装bash工具,则可执行文件将安装为/usr/local/opt/coreutils/libexec/gnubin/readlink - redolent
截至2023年10月,在macOS Sonoma上,readlink -f可以直接使用,无需GNU coreutils - undefined

175

对于目录使用这个(在bash中,**后面的/是必需的,以将其限制为目录):

ls -d -1 "$PWD/"**/

这是为了查找当前目录下直接包含一个.的文件和目录而设计的:

ls -d -1 "$PWD/"*.*

这是为了万事万物而存在的:

ls -d -1 "$PWD/"**/*

从这里获取的信息 http://www.zsh.org/mla/users/2002/msg00033.html

在bash中,如果启用shopt -s globstar**将具有递归的功能。


2
ls -d -1 $PWD// 不会递归。真希望我能收回我的+1。你可以使用*来遍历每个深度。 - user606723
7
“**”运算符是一个递归的通配符操作符。如果你在支持该操作符的shell环境(例如zsh)中使用该命令,它将能够正常工作。 - zebediah49
ls -d1 "$PWD/"{*,.*}以便捕获隐藏的(点)文件。 对于我来说,答案中的递归版本没有在子文件夹中的文件前缀绝对路径。 - Zael
我想我必须使用find命令... 我得到的错误是 -> bash: /bin/ls: 参数列表太长 - TelamonAegisthus
我的首选是在递归所有子目录时使用 ls -altd ../{path}/**/*。 - randyslavage

52
你可以使用

find $PWD 

在bash中


6
这将显示当前目录的路径,以及其下所有文件和目录。这可能不是人们想要查找的内容。 - Bill

38
ls -d "$PWD/"*

这仅在当前目录中查找。它使用引号括起"$PWD"以防其包含空格。


这仍然是一个非常有效的答案,但最好包括这个信息:它不支持递归(事实上这正是我在寻找的!) - bbbco
3
用于递归使用:find . -exec ls -ld $PWD/{} ; - Learner

16

命令:ls -1 -d“$PWD /”*

这将给出类似下面的文件的绝对路径。

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

15

你可以做到

ls -1 | xargs realpath

如果需要指定绝对路径或相对路径,也可以这样做

ls -1 $FILEPATH | xargs realpath

1
ls -1 是管道 ls 的默认设置:https://unix.stackexchange.com/a/410557/537347 - YouJiacheng

12

试试这个:

find "$PWD"/

您可以在工作目录中获得绝对路径列表


如果$PWD包含空格,则无法工作.. :) - 1234

10

$PWD是Matthew提供的一个不错的选择。如果你想让find命令只打印文件,那么你还可以添加“-type f”选项来搜索普通文件。其他选项包括只搜索目录等等。所以在你的情况下,如果我想要搜索扩展名为.c的文件,命令应该是:

find $PWD -type f -name "*.c" 

如果您想要所有文件:

find $PWD -type f

注意:您无法为上述命令创建别名,因为当bash设置别名时,$PWD会自动完成为您的主目录。

实际上,-d并不仅表示目录,而是将目录视为文件。因此,如果您ls -d /home,则会返回“/home”,而不是/home中的内容清单。 - Travis
@Travis:他说的是查找选项,而不是ls命令。在他的情况下,“find / -type d”只会查找目录 - 就像他说的那样。 - oligofren

8

如果您在find命令中输入绝对路径,它将以绝对路径形式返回结果。 因此,如果您在Ken目录中键入以下内容:

find /home/ken/foo/ -name bar -print    

你应该使用绝对路径而不是相对路径 find . -name bar -print

你应该得到:

/home/ken/foo/bar

因此,如果你想要一个ls -l并返回绝对路径,你可以告诉find命令在它找到的任何东西上执行ls -l
find /home/ken/foo -name bar -exec ls -l {} ;\ 

注意: {}; 之间有一个空格。

你会得到类似于这样的东西:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

如果您不确定文件在哪里,您可以随时更改搜索位置。只要搜索路径以“/”开头,就会返回绝对路径。如果您正在搜索一个位置(如 / ),您可能会得到很多“权限被拒绝”的错误提示,我建议您重定向标准错误输出,这样您就能够实际看到查找结果了:
find / -name bar -exec ls -l {} ;\ 2> /dev/null

(2>是Borne和Bash shells的语法,但在C shell中无法使用。它可能也适用于其他shell,但我只知道它在Bourne和Bash中可以使用)。


2
你可以使用-exec ls -ld {} +向相同的ls进程传递多个参数(可能需要使用-d来避免列出目录内容)。更好的做法是,使用find的内置ls,并使用find ... name bar -ls。另外,对于每个命令一个参数的语法错误:您必须从shell中引用分号,因此为{} \; - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接