Shell 脚本:如何在 for 中使用 find 表达式?

Shell 脚本:如何在 for 中使用 find 表达式?

我想find在 中使用该命令for。因此我执行了以下操作:

for logs in `find $BACKUP_FOLDER -exec ls -la {} \; | awk '{ if ( $8==2011) printf $0"\n" }'`; do
// some command here
done;

但它似乎不起作用,所以如果我尝试找出命令是如何被解释的,我会将这一行单独放在我的脚本中:

echo "$BACKUP_FOLDER -exec ls -la {} \; | awk { if ( '$8'==2011) printf $0"\n" }";

并且$8出现空白,并且\n也是空白。这是在终端中打印的内容

/company-logs/engine -exec ls -la {} \; | awk { if ( ''==2011) printf /company/scripts/server/backup/sync_backup.shn }

我怎样才能解决这个问题 ?

答案1

你的问题

echo "$BACKUP_FOLDER -exec ls -la {} \; | awk { if ( '$8'==2011) printf $0"\n" }";

不会显示任何有用的内容,原因有二:

  • 为了看到 shell 执行的命令,您必须使用反斜杠转义特殊$字符。"

  • $8只是 bash 的第八个命令行参数。要查看 awk 会用什么来替换它,请执行以下命令:

    find $BACKUP_FOLDER -exec ls -la {} \; | awk '{ if ( $8==2011) printf $0"\n" }'
    

您的方法

您的 for 循环不起作用,因为printf $0打印了整行ls -l(包含权限、所有者、日期和时间)。

为了修复这个问题,你必须使用例如 awk 本身或 cut 来消除除裸文件名之外的所有内容:

for logs in `find "$BACKUP_FOLDER" -exec ls -la {} \; | awk '{ if ( $8==2011) print $0 }' | cut -c 43-`; do ... done

如果文件名中有空格,这将产生问题。将内部文件分隔符设置为仅换行符(IFS=$'\n'在 bash 中)应该可以解决空格问题。

你的问题

您的方法不太可移植,因为不同版本的 ls 或不同的语言环境可能会改变字段。

要处理 2011 年的所有文件,我不会使用你的方法,而是使用

for logs in $(find "$BACKUP_FOLDER" -exec bash -c '[[ "$(stat -c %y "$0")" =~ ^2011 ]]' {} \; -print); do ... done

或者,如果可能的话,

find "$BACKUP_FOLDER" -exec bash -c '[[ "$(stat -c %y "$0")" =~ ^2011 ]]' {} \; -exec ... \;

再次,修改 IFS 应该考虑空格,但第二种方法会更可靠。

find用当前处理的文件替换{}并将其作为参数传递给 bash,bash 可以将其作为 来访问$0

stat -c %y "$0"显示 的修改时间$0[[ "$(...)" =~ ^2011 ]]检查它是否以 开头2011

如果是,则bash -c '...'返回 true 并-print打印文件名或-exec执行命令。

相关内容