ChatGPT解决这个技术问题 Extra ChatGPT

ls 命令:如何获得递归完整路径列表,每个文件一行?

如何让 ls 吐出递归单行路径的平面列表?

例如,我只想要一个包含完整路径的文件的平面列表:

/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt

ls -a1 几乎可以满足我的需要,但我不想要路径片段,我想要完整路径。

另请参阅: tree
tree -aflix --noreport 但如果您使用树并且路径中有任何符号链接,您将不得不处理这些链接或使用建议答案之一的替代解决方案。

J
Jonathan Leffler

使用查找:

find .
find /home/dreftymac

如果您只想要文件(省略目录、设备等):

find . -type f
find /home/dreftymac -type f

--sort=extension 之类的 ls 参数可以通过此解决方案“赎回”吗?
您甚至可以使用 printf 输出来显示所需的上下文信息(例如 find . -type f -printf '%p %u\n')
这可以用 falg 格式化吗? IE。 python pprint.pprint(文件)
@Shayan find-printf 谓词允许您做所有 ls 所做的事情,然后是一些。但是,它不是标准的。您可以使用 find -exec stat {} \;,但遗憾的是 stat 的选项也不是标准化的。
...最后,不幸的是,最便携的解决方案可能是 Perl 或 Python 脚本。
a
approxiblue

如果您真的想使用 ls,请使用 awk 格式化其输出:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'

有人可以解释一下上面的 awk 表达式吗?
此解决方案不会省略目录(每个目录都有自己的行)
谢谢。顺便说一句,如果能在 1 行中快速复制和粘贴,那就太好了。
将此添加到您的 .bashrc 文件:function lsr () { ls -R "$@" | awk ' /:$/&&f{s=$0;f=0} /:$/&&!f{sub(/:$/,"");s=$0;f=1;next} NF&&f{ print s"/"$0 }' },以便您可以使用 lsr /path 在任何地方使用它
您介意解释一下 awk 代码吗?看起来您正在使用正则表达式来捕获以“:”结尾的行(带有父目录路径的“标题”),但在那之后我迷路了,绝对不明白最后一个字段 NF 所在的部分被评估为真/假。谢谢!
o
others

ls -ld $(find .)

如果要按修改时间对输出进行排序:

ls -ltd $(find .)


-bash: /bin/ls: 参数列表太长
+1 为我工作了 12106 个文件,我可以使用 ls--sort=extension 参数
谢谢。我自己不会想到那种(又好又短的)语法——我会使用 find . -name "*" -exec ls -ld '{}' \; (不管文件的数量是多少,它都可以工作),但是你的命令写起来要短得多;)
ls -ld $(find .) 如果我列出一个文件有空格的 ntfs 磁盘,我会中断: ls: cannot access ./System: No such file or directory but find with quotes by @SRG works
一个较短的替代方案(取决于您的需要)是 find . -ls
t
tripleee

最佳命令是:tree -fi

-f 打印每个文件的完整路径前缀 -i 不打印缩进

例如

$ tree -fi
.
./README.md
./node_modules
./package.json
./src
./src/datasources
./src/datasources/bookmarks.js
./src/example.json
./src/index.js
./src/resolvers.js
./src/schema.js

为了使用文件而不是链接,您必须从输出中删除 >

tree -fi |grep -v \>

如果您想了解每个文件的性质,(例如只读 ASCII 文件)尝试 while 循环:

tree -fi |
grep -v \> |
while read -r first ; do 
    file "${first}"
done |
grep ASCII

@Nakilon 最接近的是什么?它是否同样显示输出?您如何使用简短的命令轻松显示类似的输出?
@om01:在 osx 上,brew install tree 很困难,因为您使用的是自制软件
我无法独家列出文件。它也总是列出目录。我怎样才能做到这一点?
@kommrad 您可以调整 file 示例并将管道转换为 grep -v directory
k
kenorb

尝试以下更简单的方法:

find "$PWD"

find "`pwd`" 如果路径包含空格或其他一些特殊字符。
这与 find . 有何不同? -.-
@SalmanPK 如果您给出像 pwd 这样的绝对路径开始,它将打印绝对路径。顺便说一句,“这与 find 有何不同”;-)
find 不带参数在某些平台上是语法错误。如果不是,则只有 find 等效于 find .
S
Sushant Verma

哦,答案真的很长。它帮了很多忙,最后,我创建了自己正在寻找的东西:

列出目录及其子目录中的所有文件:

find "$PWD" -type f

列出目录及其子目录中的所有目录:

find "$PWD" -type d

列出目录及其子目录中的所有目录和文件:

find "$PWD"

并按扩展名过滤:find "$PWD" -type f | grep '\.json$'
不需要使用 grep 进行后处理,在 find 中使用 -name 如下:find "$PWD" -type f -name *.json 如果你想删除列出的文件:find "$PWD" -type f -name * .json -exec rm {} \;同样,如果要复制它,则将 rm 替换为 cp 和目标:-exec cp {} 目标
在我的情况下必须使用“$PWD/”:find“$PWD/”-type f;
并列出具有完整路径的特定文件 find "$PWD/README.md"
J
Justin Johnson

我不知道完整路径,但您可以使用 -R 进行递归。或者,如果你不喜欢 ls,你可以只做 find *


R
Ry-
du -a

对于某些无法使用 find/locate 的有限设备外壳非常方便。


知道如何在没有 awk 的情况下删除文件大小吗?
I
Idelic

不使用 ls 以外的任何外部命令:

ls -R1 /path | 
  while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done

未知选项“-1”。中止。
@ilw 这很奇怪;我认为 ls -1 相当 standard;但如果它不受支持,请尝试将其排除在外。该选项的目的是强制 ls 每个文件打印一行,但这通常是其开箱即用的行为。 (但当然,don't use ls in scripts.)(查看 POSIX doco,此选项传统上仅适用于 BSD,但在 2017 年在 POSIX 中引入。)
所有子文件夹都将在列表中,而不仅仅是文件。
a
apaderno

找到/会做的伎俩


D
David Golembiowski

使用以下格式运行 bash 命令:

find /path -type f -exec ls -l \{\} \;

同样,要删除 -l 详细信息并仅返回绝对路径:

find /path -type f -exec ls \{\} \;

find -ls 避免为每个文件运行外部进程,并且更易于键入。
您不需要 -exec ls \{\} \; 部分,因为 find 的默认行为是打印完整路径。也就是说,如果您不需要来自 ls -l 的文件属性,find /path -type f 就可以完成这项工作。
o
oers

对于所有未来的人来说,最简单的方法就是:

du

但是,这也显示了每个文件夹中包含的内容的大小您可以使用 awk 仅输出文件夹名称:

du | awk '{print $2}'

编辑-对不起,对不起,我的错。我认为只需要文件夹。我会把它留在这里,以防将来有人需要它......


有趣,因为它向我展示了我不知道我想知道的东西——有点像谷歌建议的。事实证明,我喜欢知道每个文件占用多少空间。
h
halfer

不要让它变得复杂。我刚刚使用它并得到了一个漂亮的输出:

ls -lR /path/I/need

OP 只想要完整的路径,别无其他。 ls -lR 无法实现该目标。
对不起,它不这样做
对不起,伙计,不符合要求。如果您需要完整路径的列表,则不会以这种方式获得。至少在 BSD 或 MacOS 上不使用 bash 或 zsh
G
Grzegorz Luczywo

可以自由使用所有可能的 ls 选项:

find -type f | xargs ls -1


D
Dimitrios

我认为对于平面列表,最好的方法是:

find -D tree /fullpath/to-dir/ 

(或为了将其保存在 txt 文件中)

find -D tree /fullpath/to-dir/ > file.txt

在 Mac OS 10.13.3 上试过。 find: illegal option -- D
K
Kevin

这是显示目录名称的部分答案。

ls -mR * | sed -n 's/://p'

解释:

ls -mR * 列出以“:”结尾的完整目录名称,然后分别列出该目录中的文件

sed -n 's/://p' 查找以冒号结尾的行,去掉冒号并打印该行

通过遍历目录列表,我们也应该能够找到目录。仍在努力。通过 xargs 获取通配符是一个挑战。


很好的答案..正是我需要的!
k
koeselitz

在 ls 目录的末尾添加通配符会强制使用完整路径。现在你有这个:

$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt

你可以这样做:

$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt

不幸的是,这不会打印递归到的目录的完整路径,因此它可能不是您正在寻找的完整解决方案。


同样不幸的是,您不能 sudo ls 使用通配符(因为通配符已作为普通用户扩展)。
同样不幸的是,ls 有很多讨厌的极端情况;见parsing ls
S
Steve

我看到很多答案。这是我的,如果你在 Mac 上工作,我认为它非常有用。

我确定您知道有一些“捆绑”文件(.app.rtfd.workflow 等)。看着 Finder 的窗口,它们似乎是单个文件。但他们不是。并且 $ ls$ find 将它们视为目录...因此,除非您还需要列出它们的内容,否则这对我有用:

find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"

当然,这是针对工作目录的,您可以添加其他捆绑包的扩展名(但总是在它们后面加上 /)。或者任何其他扩展,如果不是没有 / 的捆绑包。

.lpdf/”(多语言 pdf)相当有趣。它在 Finder 中具有正常的“.pdf”扩展名 (!!) 或没有。这样你就得到(或者它只计算 1 个文件)这个 pdf 而不是一堆东西......


s
sivi

ls -lR 是您正在寻找的东西,或者至少是我正在寻找的东西。干杯


OP 只想要完整的路径,别无其他。 ls -lR 无法实现该目标。
t
tripleee

如果目录作为相对路径传递,并且您需要在调用 find 之前将其转换为绝对路径。在以下示例中,目录作为第一个参数传递给脚本:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find "$directory"

如果您的系统有 readlink,您可以执行 directory=$(readlink -e $1)
没错,但是 cd/pwd 组合将适用于每个系统。 OS X 10.5.8 上的 readlink 不支持 -e 选项。
D
Diego C Nascimento
tar cf - $PWD|tar tvf -             

这很慢,但递归地工作并打印目录和文件。如果您只想要文件名而不需要所有其他信息/目录,则可以使用 awk/grep 对其进行管道传输:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          

您也可以简单地使用: tar cvf /dev/null $PWD
P
Pavlo Neiman

当前位置的所有文件的递归列表:

ls -l $(find . -type f)


更好的是 find . -type f -ls,如果 find 的输出对于 ls 来说太长,它不会阻塞
P
Paul Rougieux

realpath 命令打印解析的路径:

realpath *

要包含点文件,请将 ls -a 的输出通过管道传输到 realpath:

ls -a | xargs realpath

递归列出子目录:

ls -aR | xargs realpath

如果文件名中有空格,man xargs 建议使用 -o 选项以防止文件名被错误处理,这最适合 find -print0 的输出,并且它开始看起来比其他答案复杂得多:

find -print0 |xargs -0 realpath

另请参阅 Unix 和 Linux stackexchange question on how to list all files in a directory with absolute path


B
Brian Burns

我知道文件名,但也想要目录。

find $PWD | fgrep filename

在 Mac OS 10.12.1 中完美运行


在终端中的 MacOS 10.15.7 上也像魅力一样工作,使用 zsh 作为默认 shell。太棒了,谢谢!
这是相当不精确和低效的。更好的尝试是find . -name filename
t
tripleee

@ghostdog74:对您的解决方案稍作调整。以下代码可用于搜索具有完整绝对路径的文件。

sudo ls -R / | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }' | grep [file_to_search]

M
Mirko Cianfarani

如果您必须搜索 100 Gb 或更多的大内存。我建议执行 @kerkael posted 而不是 findls 的命令 tree

然后执行命令 tree,唯一的区别是,我建议将输出写入文件。

例子:

tree -fi > result.txt

之后,使用像 grep -i "*.docx" result.txt 这样的模式在文件中执行 grep command,这样您就不会浪费时间,这种方式在大内存上搜索文件的速度更快。

https://i.stack.imgur.com/dSJzg.png