我想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
执行命令。