我的目的是显示目录和文件(只有在树结构中才有.dat或.DAT文件扩展名)。下面的例子是我在bash脚本中的代码,它返回了这些文件,但也返回了.txt / .xmlfd扩展名的文件。有人能指出我的代码有什么问题吗?
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f | grep -i '*.dat' | sort -u | xargs tree -L 3 -C'
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f -iname '*.dat' -exec dirname {} \; | sort -u | xargs tree -L 3 -C'
sudo -${user} sh -c 'cd '${userdirectory}'; find . -type f -name '*.[dD][aA][tT]' -exec dirname {} \; | sort -u | xargs tree -L 3 -C'
2条答案
按热度按时间s4n0splo1#
你的grep regex没有多大意义:正则表达式开头的星号具有字面星号的含义,并且仅当
find
生成的文件名中包含星号时才匹配。句点匹配任何字符,因此,grep
基本上是在文件名中搜索子字符串,如*xdat
或*%dat
。如果搜索文件名以.dat
,grep for[.]dat$
:字符串
[.]
匹配文字点,$
将匹配锚定在行尾。或者,您可以让
find
进行选择,通过指定一个glob模式,型
或者如果你想使用正则表达式,
型
当然,所有这些都要求你的文件名不包含换行符。
在任何情况下,都要确保引号是正确的:如果整个字符串都用单引号括起来,则需要对 find 或 grep 命令的单引号进行转义。
erhoui1w2#
有谁能告诉我我的代码有什么问题吗?
tree
需要 directories,所以你的基本前提被打破了。你不能用这种方式在一个特定的 file 参数列表上调用它,但是看起来你真正需要的只是
-P
让它自己做那个选择。字符串
(The
-L 3
正在工作:)型
为了详细说明你实际提出的问题,让我们看看你遇到的一些具体问题。
型
1.我想你是说
sudo -u $user
。1.修正你的引用。
1.修复正则表达式(或其他文件限制方法)。
tree
需要目录,见上文。解决每个-
sudo -${user}
将用户名作为一个选项堆栈传递,其中一些选项可能需要也可能不需要参数,并在语法上中断-您应该希望它们这样做。型
大多数引号并不嵌套。最好的做法是引用变量,除非你有一个很好的,具体的理由不这样做,所以利用单和双之间切换时,你可以。
请记住,单引号防止变量插值,因此如果您的变量存在于当前环境中,则需要在分析该行时让shell插入它,* 在 * 将结果命令发送到
sudo
之前。请注意,如果一组引号位于另一组引号内,则外部通常定义插值和 * 内部 * 引号规则:
型
因此,
型
这将传递单引号以保护
${userdirectory}
中的任何嵌入空格,但仍将在将整个内容传递给sudo
之前插入${userdirectory}
的 * 值 * 作为。请注意,如前所述,如果
cd
失败,它将执行任何剩余的命令,无论它在哪里。通常,如果可能的话,最好检查一下。例如,型
给定的
find
将返回当前目录下的所有普通文件。正如user 1934428所指出的,-iname
将允许您返回不区分大小写的匹配,无需单独的grep
。型
顺便说一句,
grep
使用的是正则表达式,而不是globs。你的grep -i '*.dat'
应该是grep -i '\.dat$'
--尽管如此,正如user 1934428所指出的,在做这类事情时不要使用grep
,即使你更喜欢正则表达式而不是globbing;您仍然可以以相同的方式消除额外的进程,但使用-iregex '[.]dat$'
而不是-iname '*.dat'
,如型
通过一个简单的词法
sort
传递也可能不会达到您想要的效果,但是如果您搜索的话,这确实是另一个广泛存在的讨论。正如我们上面提到的,
find
根本不是你所需要的,所以xargs
也变得多余了(更不用说-exec
了)。如果你正在做一些有用的事情,请参考BashFAQ #20,这里有很好的例子和解释。.但你不需要
find
* 或 *xargs. Just call
树with the
-P`模式。型
要知道
tree
是“globbing”,所以它不是一个真实的正则表达式,但是它也可能没有shell提供的所有功能。例如,设置shopt -s nocaseglob
似乎不起作用,因为它可能没有复制到tree
的子shell中。这意味着要同时匹配大小写,您可以使用
-P '*.dat|*.DAT'
,但这不会匹配名为foo.Dat
的文件,而-P '*.[dD][aA][tT]'可以。相应地选择。-v
应该有助于排序。使用--prune
和--dirsfirst
可以在您想要的位置获得输出,例如消除输出中没有任何有效命中的目录。