bash - 结合 unix find 命令选项
问题描述
我编写了一个在 macOS 10.l0.5 上运行的 bash 脚本。我希望简化脚本。在下面的示例脚本中,第一次调用 find 命令会给出所需的输出。在原始脚本中,我有多个查找命令,其中排除了同一组目录。我希望将它们放在一个变量中。第二个 find 命令显示我失败的尝试。
我不知道为什么这失败了。
我可以接受在多个查找命令之间共享通用选项的任何方式。不,我不想排除所有隐藏目录。
我使用外部闪存驱动器运行它。这个脚本都是只读的。
#! /bin/bash
sourceDir="/Volumes/DOSDISK"
echo "--------------- find works as expected ------------------------------"
find ${sourceDir} \
! -path "${sourceDir}/.Trashes" \
! -path "${sourceDir}/.Trashes/*" \
! -path "${sourceDir}/.Spotlight-V100" \
! -path "${sourceDir}/.Spotlight-V100/*" \
! -path "${sourceDir}/.fseventsd" \
! -path "${sourceDir}/.fseventsd/*" \
-type d \
-exec echo {} \;
echo "----------------------------- does not skip hidden directories -----------"
dirsToSkip=" ! -path \"${sourceDir}\" "
echo "dirsToSkip is -1->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.Trashes\" "
echo "dirsToSkip is -2->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.Trashes/*\" "
echo "dirsToSkip is -3->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.Spotlight-V100\" "
echo "dirsToSkip is -4->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.Spotlight-V100/*\" "
echo "dirsToSkip is -5->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.fseventsd\" "
echo "dirsToSkip is -6->${dirsToSkip}"
dirsToSkip="${dirsToSkip}! -path \"${sourceDir}/.fseventsdf/*\" "
echo "dirsToSkip is -7->${dirsToSkip}"
echo "see in print ---> "find ${sourceDir} \
${dirsToSkip} \
-type d \
-exec echo {} \;
echo -e "\n The non-working thing. "
find ${sourceDir} \
${dirsToSkip} \
-type d \
-exec echo {} \;
输出。向脚本添加调试时 #! /bin/bash -v -x,我注意到了!打印为“!”。
mac $ ./config/trybash.bash
--------------- find works as expected ------------------------------
/Volumes/DOSDISK
/Volumes/DOSDISK/level2
/Volumes/DOSDISK/level3
----------------------------- does not skip hidden directories -----------
dirsToSkip is -1-> ! -path "/Volumes/DOSDISK"
dirsToSkip is -2-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes"
dirsToSkip is -3-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*"
dirsToSkip is -4-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*" ! -path "/Volumes/DOSDISK/.Spotlight-V100"
dirsToSkip is -5-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*" ! -path "/Volumes/DOSDISK/.Spotlight-V100" ! -path "/Volumes/DOSDISK/.Spotlight-V100/*"
dirsToSkip is -6-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*" ! -path "/Volumes/DOSDISK/.Spotlight-V100" ! -path "/Volumes/DOSDISK/.Spotlight-V100/*" ! -path "/Volumes/DOSDISK/.fseventsd"
dirsToSkip is -7-> ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*" ! -path "/Volumes/DOSDISK/.Spotlight-V100" ! -path "/Volumes/DOSDISK/.Spotlight-V100/*" ! -path "/Volumes/DOSDISK/.fseventsd" ! -path "/Volumes/DOSDISK/.fseventsdf/*"
see in print ---> find /Volumes/DOSDISK ! -path "/Volumes/DOSDISK" ! -path "/Volumes/DOSDISK/.Trashes" ! -path "/Volumes/DOSDISK/.Trashes/*" ! -path "/Volumes/DOSDISK/.Spotlight-V100" ! -path "/Volumes/DOSDISK/.Spotlight-V100/*" ! -path "/Volumes/DOSDISK/.fseventsd" ! -path "/Volumes/DOSDISK/.fseventsdf/*" -type d -exec echo {} ;
The non-working thing.
/Volumes/DOSDISK
/Volumes/DOSDISK/.Trashes
/Volumes/DOSDISK/.Trashes/501
/Volumes/DOSDISK/.Trashes/501/.Spotlight-V100
/Volumes/DOSDISK/.Trashes/501/.Spotlight-V100/Store-V2
/Volumes/DOSDISK/.Trashes/501/.Spotlight-V100/Store-V2/FF996064-BEDD-474E-9E76-7F8ABD688B09
/Volumes/DOSDISK/.Spotlight-V100
/Volumes/DOSDISK/.Spotlight-V100/Store-V2
/Volumes/DOSDISK/.Spotlight-V100/Store-V1
/Volumes/DOSDISK/.fseventsd
/Volumes/DOSDISK/level2
/Volumes/DOSDISK/level3
mac $
解决方案
根据从这个线程中得到的建议,我开发了这个脚本。要运行,您需要将变量 sourceDir 更改为您的目录之一的路径。这是仅打印到控制台的脚本。
#! /bin/bash
#
# Answer to my question:
# https://stackoverflow.com/questions/56926105/combining-unix-find-command-options?noredirect=1#comment100396210_56926105
# see Gordon Davisson's comment
#
sourceDir="/Volumes/DOSDISK"
echo "--------------- find works as expected ------------------------------"
find ${sourceDir} \
! -path "${sourceDir}" \
! -path "${sourceDir}/.Trashes" \
! -path "${sourceDir}/.Trashes/*" \
! -path "${sourceDir}/.Spotlight-V100" \
! -path "${sourceDir}/.Spotlight-V100/*" \
! -path "${sourceDir}/.fseventsd" \
! -path "${sourceDir}/.fseventsd/*" \
-type d \
-exec echo {} \;
echo "----------------------------- Another way to skip hidden directories -----------"
# You place one and only one argument in each array element.
# avoid add extraneous leading and trailing blanks.
# No need to double quote strings.
#
fileargs=()
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.Trashes")
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.Trashes/*")
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.Spotlight-V100")
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.Spotlight-V100/*")
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.fseventsd")
fileargs+=("!")
fileargs+=("-path")
fileargs+=("${sourceDir}/.fseventsdf/*" )
echo "fileargs are -->${fileargs[@]}<--"
# This invocation is optional. Remove comments to see
# the arguments printed out
# you will need the associated bash file.
#echo -e "\n Print args. "
#/Users/mac/config/displayinput.bash ${sourceDir} \
# ! -path "${sourceDir}" \
# "${fileargs[@]}" \
# -type d \
# -exec echo {} \;
echo -e "\n A second working thing. \n"
find ${sourceDir} \
! -path "${sourceDir}" \
"${fileargs[@]}" \
-type d \
-exec echo {} \;
exit 0
这是可选的 displayinput.bash 脚本
#! /bin/bash
# display input
echo -e "\nin displayinput.bash"
echo -e "\nall args -->${*}<--\n"
declare -i position
position="1";
while [[ $# -gt 0 ]]
do
key="$1"
echo "input #${position} token ${1}"
shift # past argument
position="position + 1";
done
推荐阅读
- azure-devops - Azure DevOps:通过连接其他变量的值作为任务输入来获取变量值
- javascript - 如何在没有 jQuery 的情况下使用 JavaScript 使背景图像褪色?
- python - 如何将每个数组存储在一行中
- python - 什么时候可以在 Python 中使用空格来提高可读性?
- intellij-idea - 量角器找不到环境/环境
- excel - 如何在没有 VBA 的情况下使用函数将 Excel 时间解析为不同的格式?
- java - 为候选人挑选弹簧多个级别
- aws-lambda - AWS Pinpoint 自定义通道:无法正确调用挂钩中指定的 Lambda 函数
- amazon-ec2 - 如何将我的 ec2 实例共享给我组织内的其他账户?
- javascript - 在 slideToggle 回调中传递动态创建的 ID