我正在尝试在 Debian Jessie 主机上编写脚本。
我在尝试在脚本中运行以下命令(有一些变化)时遇到问题:
find ~/* -path ~/FileSniper* \
-prune -o \
-type f \( -name "*.mp4" -o -name "*.sh" -or -name "*.mp3" \) \
! -name '*.txt' -printf "%f\n"
我在脚本中尝试做的是让用户必须输入他/她想要搜索的文件格式,之后,我将其通过管道传输到sed
,这将确保它获得正确的格式:
echo "Input the formats like this: \"mp3,mp4,exe,sh\""
read -p "input:" formats
formattedformats=`echo "-name \"*.""$formats""\"" | sed 's/,/" -o -name "*./g'`
find_parameters=(\(formattedformats\))
这里的遗嘱$find_parameters
将包含如下内容:
-name "*.mp3" -o -name "*.mp4" -o -name "*.sh"
我无法弄清楚这一行有什么问题:
find ~/* -path ~/FileSniper* -prune -o -type f "${find_parameters[@]}" ! -name "*.txt" -printf "%f\n" > foundfiles.txt
我已经尽我所能进行了研究,但仍然无法找出问题所在。请指出我正确的方向。
答案1
这是一个从命令行(而不是从标准输入)读取文件扩展名并使用它们构建正则表达式以与find
's-iregex
选项一起使用的脚本。
它排除隐藏.
目录,~/FileSniper*
如原始示例所示。
#! /bin/bash
regexp=''
for ext in "$@" ; do
[ -n "$regexp" ] && regexp="$regexp\|"
regexp="$regexp.*\.$ext$"
done
find ~ -not -path '*/.*' -not -path '*/FileSniper*' -type f \
-iregex "$regexp" > foundfiles.txt
答案2
如果您的脚本是一种#!/bin/sh
类型或其他类型,.sh
那么它将解释为什么您的脚本${find_parameters[@]}
不能在 Debian 系统上运行,该系统使用dash
不实现${array[@]}
类型名称扩展的默认 shell 解释器。
我还可以看到你的-path ~/FileSniper*
论点可能会产生不想要的结果——~/*
这件事也是如此。正如所写,这些是 shell 扩展 - 而不是find
扩展。操作find [ ...paths... ]
数永远不会扩展,因此~/*
- 如果这确实是您想要的 - 尽可能正确,但-path ~/FileSniper*
会扩展为父 shell 可能产生的任何结果前它被用作模式find
。因此,如果它与路径不匹配,~/
那么它就是一个有争议的问题,因为*
无论如何都会保持原样,但如果它做那么它就不再按照你想要的模式工作了。
您可能应该引用它:find ... -path ~/FileSniper\*
除非您想查找文字~
代号,在这种情况下您也应该引用它。