Bash find/foo/bar*而不是find/foo-name“;酒吧*";

Bash find/foo/bar*而不是find/foo-name“;酒吧*";,bash,Bash,通常建议使用 find /foo -name "bar*" 在/foo中查找以条开始的所有文件。使用起来不是更简单吗 find /foo/bar* ??我知道bash在上一个示例中扩展了/foo/bar*,而不是查找本身,但是否存在任何风险 我的用例是,我希望将命令find存储在变量中,例如 FINDSTRING='/foo -name "bar*"' FILES=`find $FINDSTRING` 哪一个不起作用,或者 FINDSTRING='/foo -name bar*' FILE

通常建议使用

find /foo -name "bar*"
/foo
中查找以
条开始的所有文件。使用起来不是更简单吗

find /foo/bar*
??我知道bash在上一个示例中扩展了
/foo/bar*
,而不是
查找
本身,但是否存在任何风险

我的用例是,我希望将命令
find
存储在变量中,例如

FINDSTRING='/foo -name "bar*"'
FILES=`find $FINDSTRING`
哪一个不起作用,或者

FINDSTRING='/foo -name bar*'
FILES=`find $FINDSTRING`
如果当前目录中有
bar*
文件,则此选项不起作用,但是

FINDSTRING='/foo/bar*'
FILES=`find $FINDSTRING`
确实有效

在本例中,
bash
正在扩展通配符(
*
),而不是
find
<代码>查找
尝试将文件列表作为名称模式文件进行评估。所以它不起作用

否则,
-name
选项允许我们使用特定的名称文件模式,例如:

sudo find / -name "[0-9]*"
在本例中,
bash
正在扩展通配符(
*
),而不是
find
<代码>查找
尝试将文件列表作为名称模式文件进行评估。所以它不起作用

否则,
-name
选项允许我们使用特定的名称文件模式,例如:

sudo find / -name "[0-9]*"
如果当前目录中有bar*文件,则该选项不起作用,但是

FINDSTRING='/foo/bar*'
FILES=`find $FINDSTRING`
您可以通过在参数周围使用单引号防止Bash扩展
FINDSTRING
中的
*
来解决此问题:

FINDSTRING="/foo -name 'bar*'"
不要让Bash进行扩展(如果这样做,那么使用
find
有什么意义,因为Bash已经生成了匹配文件的列表?)

如果当前目录中有bar*文件,则该选项不起作用,但是

FINDSTRING='/foo/bar*'
FILES=`find $FINDSTRING`
您可以通过在参数周围使用单引号防止Bash扩展
FINDSTRING
中的
*
来解决此问题:

FINDSTRING="/foo -name 'bar*'"

不要让BASH做扩展(如果你做了,使用“<代码>查找< /COD>”有什么意义,因为BASH已经生成了匹配文件的列表?)< /P> < P>,而不是在变量中存储整个<代码>查找< /代码>命令,在变量中考虑这样的变量:存储路径和GLUB模式:

fpath='/foo'
fname='bar*'
然后按以下方式运行find命令:

find "$fpath" -name "$fname"

<>而不是在变量中存储整个<代码>查找< /COD>命令,在变量中考虑这样的存储路径和GLUB模式:

fpath='/foo'
fname='bar*'
然后按以下方式运行find命令:

find "$fpath" -name "$fname"

使用数组存储命令选项,而不是平面字符串:

find_options=( /foo -name "bar*" )
files=$( find "${find_options[@]}" )

如果文件名包含空格,则尝试将文件列表存储在字符串中还存在其他问题,但这是另一个问题。

使用数组存储命令选项,而不是平面字符串:

find_options=( /foo -name "bar*" )
files=$( find "${find_options[@]}" )

如果文件名包含空格,则尝试将文件列表存储在字符串中还有其他问题,但这是另一个问题。

find/foo/bar*
仅搜索在/foo目录顶层以“bar”开头的文件名。例如,如果/foo/qux/bar.txt存在,
find/foo-name“bar*”
会找到它,但
find/foo/bar*
不会

现在,对于将命令存储在变量中,简短的回答是不能(至少在普通变量中)。有一些选项可以执行类似于将其存储在变量中的操作,但您应该使用哪个选项取决于您希望将其存储在变量中的原因。涵盖了这一点,但这里是简短的总结

  • 如果在执行命令之前没有充分的理由将命令存储在变量中,那么就不要这样做。存储和检索命令可能会很混乱,如果没有充分的理由,只需跳过整个混乱,直接执行命令即可

  • 如果需要动态生成命令,可以将命令(或仅其参数)存储在数组中(如chepner建议的):

    正如切普纳所指出的,如果文件名中有空格,这将失败。您确实应该将文件名存储为数组:

    find_options=(/foo -name "bar*")
    
    files=()
    while IFS= read -r -d '' file; do
        files+=("file")
    done < <(find "${find_options[@]}")
    
    dostuffwith "${files[@]}"
    
    find_options=(/foo-name“bar*”)
    文件=()
    而IFS=read-r-d“”文件;做
    文件+=(“文件”)
    
    完成<
    查找/foo/bar*
    仅搜索在/foo目录顶层以“bar”开头的文件名。例如,如果/foo/qux/bar.txt存在,
    find/foo-name“bar*”
    会找到它,但
    find/foo/bar*
    不会

    现在,对于将命令存储在变量中,简短的回答是不能(至少在普通变量中)。有一些选项可以执行类似于将其存储在变量中的操作,但您应该使用哪个选项取决于您希望将其存储在变量中的原因。涵盖了这一点,但这里是简短的总结

    • 如果在执行命令之前没有充分的理由将命令存储在变量中,那么就不要这样做。存储和检索命令可能会很混乱,如果没有充分的理由,只需跳过整个混乱,直接执行命令即可

    • 如果需要动态生成命令,可以将命令(或仅其参数)存储在数组中(如chepner建议的):

      正如切普纳所指出的,如果文件名中有空格,这将失败。您确实应该将文件名存储为数组:

      find_options=(/foo -name "bar*")
      
      files=()
      while IFS= read -r -d '' file; do
          files+=("file")
      done < <(find "${find_options[@]}")
      
      dostuffwith "${files[@]}"
      
      find_options=(/foo-name“bar*”)
      文件=()
      而IFS=read-r-d“”文件;做
      文件+=(“文件”)
      
      done<您给出的所有三个示例都采用了不好的做法,工作不可靠--请尝试使用带有空格的文件名,或者更糟糕的是,文件名类似于
      foo*bar.txt
      。请参阅您给出的所有三个示例中的条目#1,它们都遵循错误的做法,工作不可靠--请尝试使用带有空格的文件名,或者更糟糕的是,文件名类似于
      foo*bar.txt
      。请参见中的条目#1