Find

查找 - 我如何創建別名來執行類似 (find . -iname ‘$1’) 的操作?

  • June 26, 2019

我有一個findn功能:

findn () {
   find . -iname "*$1*"
}

如果文件名包含空格,則使用此函式有一個缺點,我無法使用-print0 | xargs -0 command(我正在使用 mac)來擴展 find 命令的功能。findn filename

那麼,無論如何我可以同時保持方便的功能-iname "*$1*"| xargs command

我正在考慮使用別名來做到這一點,但它不一定是別名。

使用 GNUfind或兼容(-iname無論如何已經是 GNU 擴展)的一種方法可能是將函式定義為:

findn() (
 if [ -t 1 ]; then # if the output goes to a terminal
   action=-print  # simple print for the user to see
 else
   action=-print0 # NUL-delimited records so the output can be post-processed
 fi
 first=true
 for arg do
   if "$first"; then
     set -- "$@" '('
     first=false
   else
     set -- "$@" -o
   fi
   set -- "$@" -iname "*$arg*"
   shift
 done
 "$first" || set -- "$@" ')'
 exec find . "$@" "$action"
)

然後您可以將其用作:

findn foo bar

查看包含or的文件名(如果您想要同時包含and的文件名,請將其更改為上面的名稱)。foo``bar``-o``-a``foo bar

和:

findn foo bar | xargs -r0 cat

如果要對找到的每個文件應用命令findn

對於同時執行和不**執行的變體:

findn() (
 if [ -t 1 ]; then # if the output goes to a terminal
   action=-print  # simple print for the user to see
 else
   action=-print0 # NUL-delimited records so the output can be post-processed
 fi
 first=true
 for arg do
   if "$first"; then
     set -- "$@" '('
     first=false
   else
     set -- "$@"
   fi
   if [ "$arg" = ! ]; then
     set -- "$@" !
   else
     case $arg in
       (*[][*?\\]*)
         # already contains wildcard characters, don't wrap in *
         set -- "$@" -iname "$arg"
         ;;
       (*)
         set -- "$@" -iname "*$arg*"
         ;;
     esac
   fi
   shift
 done
 "$first" || set -- "$@" ')'
 exec find . "$@" "$action"
)

進而:

findn foo bar ! baz

對於同時包含fooandbar和 not的文件名baz

在那個變體中,我還做了這樣的設置,如果參數包含萬用字元,則按原樣處理,因此您可以執行以下操作:

findn foo ! 'bar*'

查找不以 bar*開頭的文件。*如果您使用的是zshshell,則可以創建一個別名:

alias findn='noglob findn'

要禁用允許您編寫的該命令的萬用字元:

find foo ! bar*

您可能希望創建一個腳本(這裡一個sh腳本就足夠了,因為該語法是 POSIX)而不是一個函式,因此可以從任何地方呼叫它,而不僅僅是您的 shell。

您的解決方案適用於xargs

$ echo "foo bar one" > foobarone
$ echo "foo bar two" > fooBARtwo
$ findn "bar"
./fooBARtwo
./foobarone
$ findn "bar" | xargs cat
foo bar two
foo bar one

還是我錯過了什麼?

如果你稍微修改你的函式,你可以在你的find命令中添加額外的參數:

findn () {
 local name=$1
 shift
 find . -iname "*$name*" "$@"
}

例子:

$ findn bar ! -name '*two' -print0 | xargs -0 cat
foo bar one

引用自:https://unix.stackexchange.com/questions/526936