将 sed 的解析输出传递给 find (朝这个方向)

将 sed 的解析输出传递给 find (朝这个方向)

嗯,我想你可以在这个平台上找到几十个关于如何管道的问题find 输出sed,但到目前为止我还没有找到任何相反方向的东西。我想做的是修改我的输入, 和然后将其传递给find.

假设我想做类似以下的事情,以避免输入那些繁琐的星号通配符,从而使自己的生活更轻松。 (我希望很明显,这里字符串运算符后面的表达式<<<最终计划被参数替换,例如$1,在稍后的脚本中。下面的行仅用于演示。)

$ sed 's/ /\*/g' <<< ' foo bar baz ' | find . -type f -iname - 

-这句台词的结尾实际上是应该使用 的输出sed作为 的输入find;然而,将该find部分扩展到

... find -D tree . -type f -iname - ... 

显示该参数是不是传递到find.也许您find根本无法使用管道传递预处理的输入?

答案1

find不从标准输入获取参数,而是从命令行获取参数,因此:

find . -iname "$(sed 's/ /\*/g' <<< ' foo bar baz ')"

那将变成:

find . -iname "foo*bar*baz*"

(引号是阻止 shell 扩展通配符 foo*bar*baz* 所必需的)

这可能是也可能不是您希望得到的。例如,如果您确实想要以 foo、bar 或 baz 开头的文件,而不是与模式“foo*bar*baz*”匹配的文件,那么您需要构造一个正则表达式并使用-regexor-iregex而不是-iname。或者构建一个更复杂的查找命令,例如-iname 'foo*' -o -iname 'bar*' -o -iname 'baz*'

或者:

PATTERN='foo bar baz'
PATTERN=$(echo "$PATTERN" | sed -e 's/ /*/g')
# and/or do whatever else you need to do to transform $PATTERN to be what
# you need it to be...
find . -iname "$PATTERN"

这是 bash 脚本中的一行代码。它在脚本中的工作方式与在命令行中的工作方式完全相同。

$ cat ./test.sh
#! /bin/bash 
find . -iname "$(sed 's/ /\*/g' <<< ' foo bar baz ')"

$ ls -l
total 4
-rw-r--r-- 1 cas cas  0 Sep 26 16:53 doesntmatch
lrwxrwxrwx 1 cas cas 16 Sep 26 16:59 symlink -> xfoo-ybar-zbaz01
-rwxr-xr-x 1 cas cas 69 Sep 26 16:50 test.sh
-rw-r--r-- 1 cas cas  0 Sep 26 16:50 xfoo-ybar-zbaz01
-rw-r--r-- 1 cas cas  0 Sep 26 16:50 xfoo-ybar-zbaz02
-rw-r--r-- 1 cas cas  0 Sep 26 16:50 xfoo-ybar-zbaz03

$ ./test.sh 
./xfoo-ybar-zbaz01
./xfoo-ybar-zbaz03
./xfoo-ybar-zbaz02

$ find . -iname "$(sed 's/ /\*/g' <<< ' foo bar baz ')"
./xfoo-ybar-zbaz01
./xfoo-ybar-zbaz03
./xfoo-ybar-zbaz02

$ find . -iname "*foo*bar*baz*"
./xfoo-ybar-zbaz01
./xfoo-ybar-zbaz03
./xfoo-ybar-zbaz02

答案2

为什么不使用for循环呢?

for n in $(sed 's/ /\*/g' <<< ' foo bar baz '); do find . -iname $n; done

相关内容