相对于目录的“查找”输出


34

我想用来find在给定的根目录中递归列出所有文件和目录,以进行cpio操作。但是,我不希望根目录本身出现在路径中。例如,我目前得到:

$ find diskimg
diskimg
diskimg/file1
diskimg/dir1
diskimg/dir1/file2

但是,我想得到

file1
dir1
dir1/file2

(请注意,根目录也不在我想要的输出中,但这很容易被删除tail)。

我在OS X上,如果可能的话,我不希望安装任何额外的工具(例如GNU find),因为我想与其他OS X用户共享我编写的脚本。

我知道可以通过cut切断根目录列表来完成此操作,但这似乎是次佳的解决方案。有没有更好的解决方案?


find diskimg/* | cut -d '/' -f2-
nik.shornikov

Answers:


18

如果您要执行的操作不太复杂,则可以使用sed完成此操作:

find diskimg | sed -n 's|^diskimg/||p'

cut

find diskimg | cut -sd / -f 2-

您可以为命令选择(几乎)任何分隔符,因此:(find diskimg | grep -v '^diskimg$' | sed -e 's|^diskimg/||'请注意,我还添加了“ -e”,这也是一种^很好的做法(这里没有必要,因为您确定每一行都会有此分隔符...但是仍然是很好的做法) ,并节省了一些CPU;))
Olivier Dulac

没有grep的另一种方式:( find diskimg | sed -e 's|^diskimg/*||' “ / *”将匹配任何数量的“ /”,甚至为0)
Olivier Dulac

cut命令比我使用的命令更干净。我喜欢。(sed解决方案也不错,但是重复diskimg/很不幸)。
nneonneo 2013年

30

cd 首先进入目录:

cd diskimg && find . 

完成后,您将返回到根目录。

在这种情况下,您的文件将以./开头;我看到的唯一方法是使用cut

{ cd diskimg && find .; } | tail -n +2 | cut -c 3-

使用子Shell可以避免更改Shell的当前目录(如果您正在管道输出,因为管道的左侧已经在子Shell中运行,则不需要此操作)。

(cd diskimg && find .)

5
在完成时返回原始目录:添加括号:(cd diskimg && find . ; )。这样,cd diskimg && find .就可以在子shell中完成该操作:当该子shell退出时,无论您位于哪个目录中,您都可以返回自己的shell。
Olivier Dulac 2013年

1
find *是解决无用前缀的另一种方法
nik.shornikov

23

另一个更复杂,但仅使用我的其他答案中的查找方法:

find diskimg -mindepth 1 -printf '%P\n'

并非所有版本都find支持printf
jordanm 2013年

1
一定; 看来我的OSX没有。部分原因是我提供了另一个解决方案。
Stephan

2
@Stephan-下次您可以将这些类型的答案合并为一个。无需针对此类差异做出多个答案。
slm

2
仅GNU find支持-printf,尽管许多BSD find复制了GNU的某些功能find,但-printf尚未复制(AFAIK)。
斯特凡Chazelas

%P为相对路径是我需要的。
Fl0v0

4

使用该realpath实用程序:

find diskimg -exec realpath --relative-to diskimg {} \;

整洁-感谢给我看--relative-to
nneonneo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.