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

syn*_*ror 4 bash pipe sed find parameter

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

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

$ sed 's/ /\*/g' <<< ' foo bar baz ' | find . -type f -iname - 
Run Code Online (Sandbox Code Playgroud)

-在此一衬套的端部实际上应该使用的输出sed为作为输入find; 然而,将find部分扩展到

... find -D tree . -type f -iname - ... 
Run Code Online (Sandbox Code Playgroud)

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

cas*_*cas 5

find 不从 stdin 获取其 args,而是从命令行获取它们,因此:

find . -iname "$(sed 's/ /\*/g' <<< ' foo bar baz ')"
Run Code Online (Sandbox Code Playgroud)

那将变成:

find . -iname "foo*bar*baz*"
Run Code Online (Sandbox Code Playgroud)

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

这可能是也可能不是您希望得到的。例如,如果您真的想要以 foo、bar 或 baz 开头的文件而不是匹配模式 'foo*bar*baz*' 的文件,那么您需要构造一个正则表达式并使用-regexor-iregex而不是-iname. 或者构建一个更复杂的 find 命令,比如-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"
Run Code Online (Sandbox Code Playgroud)

这是 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
Run Code Online (Sandbox Code Playgroud)