在find的exec参数中展开bash函数

时间:2012-03-16 10:01:01

标签: bash shell find expansion

如何让find在我的 exec 参数中应用我的shell定义的函数和别名?

例如,我已经定义了一个类似 bzip2 的功能,但是使用 7z

  

function 7zip(){for $ in $ @;做ls -alF“$ f”; 7za a -t7z -m0 = lzma   -mx = 9 -mfb = 64 -md = 64m -ms = on“$ f.7z”“$ f”&& touch -r“$ f”“$ f.7z”&& rm -fv“$ f”&& ls -alF“$ f.7z”;完成; }

当我发现压缩时间超过7天的文件时:

find . -mtime +7  -name "G*.html"   -execdir  7zip {}  + 

而不是扩展 7zip ,而不是错误命令找不到。

这都在shell脚本中。

4 个答案:

答案 0 :(得分:2)

您可以使用以下函数导出函数定义:

export -f 7zipi

但是使用名称以数字开头的标识符会遇到麻烦。尝试将名称更改为合理的名称。 (例如“f7zipi”或“_7zipi”)

答案 1 :(得分:1)

作为一个不耐烦的程序员,现在我把它改为多行:

hitlist=$(find . -mtime +7  -name "G*.html")
7zipi $hitlist |awk ' !x[$0]++'

那个 awk 位在那里btw是这样的,输出只打印之前看不到的线,所以它不会混乱的数字:

7-Zip (A) 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,2 CPUs)
Compressing  [Content]      
Everything is Ok

真的是答案;我仍然喜欢查找来使用我的宏。

答案 2 :(得分:1)

所有这四个命令都可以正常使用函数调用。根据需要调整您的查找规范..它们都满足文件名中的空格。就个人而言,我无法看到炮击另一个bash实例,但我已经包含了两个调用bash的版本。

IFS=$'\n'; f=($(find /tmp -maxdepth 1 -name "$USER.*")); f7zipi "${f[@]}"

IFS=; find /tmp -maxdepth 1 -name "$USER.*" | while read -r f ;do f7zipi "$f"; done 

IFS=$'\n'; bash -c 'IFS=; f7zipi "$@"' 0 $(find /tmp -maxdepth 1 -name "$USER.*")  

find /tmp -maxdepth 1 -name "$USER.*" -exec bash -c 'IFS=; f7zipi "$@"' 0 {} +;   

以下是我如何在Ubuntu 10.04中使用GNU bash 4.1.5设置该功能

顺便说一句。您应该在函数中使用local f,以便不会与调用脚本的同名变量发生冲突

这正是我添加到〜/ .bashrc

的内容
function f7zipi() { 
    local f
    for f in $@; do 
        ls -alF "$f"
        7za a -si -t7z -m0=lzma -mx=9 -mfb=64 \
        -md=64m -ms=on "$f.7z" < "$f" && 
            touch -r "$f" "$f.7z" && 
            rm -fv "$f" && 
            ls -alF "$f.7z"
    done
}
export -f f7zipi

当我只将上述函数分配到终端的bash命令行时,从该命令行运行的脚本在调用函数时失败...如果我进一步将export -f f7zipi应用于同一命令行..那么脚本成功...但是scipt仅适用于该特定命令行会话。

当函数和导出包含在~/bashrc中时,脚本每次都在任何bash会话中工作..

这是测试脚本

#!/bin/bash
f=/tmp/$USER.abc
g=/tmp/$USER.lmn
rm -fv "$f" "$f".7z
rm -fv "$g" "$g".7z
printf 'abcdefg'>"$f"
printf 'lmnopqr'>"$g"
IFS=$'\n'; f=($(find /tmp -maxdepth 1 -name "$USER.*")); f7zipi "${f[@]}"
exit

答案 3 :(得分:0)

似乎不是每个find都会接受一个函数作为--execdir的参数。它对我来说无论是原始形式还是使用export -f

但是,如果您从函数中创建一个脚本,它将起作用

find . -mtime +7 -name "G*.html" -execdir  /path/to/script_7zipi {} +