簡體   English   中英

使用排除列表在bash中查找包含find的目錄

[英]Finding directories with find in bash using a exclude list

現在在你想到之前,“這已經完成了”請繼續閱讀。

像大多數嘗試查找bash腳本的人一樣,你最終會將腳本硬編碼為單行命令,但最終會在接下來的幾個月/幾年內編輯這個東西,所以你希望最后你做得對第一次。

我現在正在編寫一個小備份程序來備份目錄並需要找到它們,而不是需要排除的Directorie列表。 說起來容易做起來難。 讓我開始吧:

#!/bin/bash
BasePath="/home/adesso/baldar"
declare -a Iggy
Iggy=( "/cgi-bin" 
    "/tmp" 
    "/test" 
    "/html" 
    "/icons" )
IggySubdomains=$(printf ",%s" "${Iggy[@]}")
IggySubdomains=${IggySubdomains:1}
echo $IggySubdomains
exit 0

現在在這結束時你得到/ cgi-bin,/ tmp,/ test,/ html,/ icons這證明這個概念有效,但是現在為了更進一步,我需要使用find來搜索BasePath並搜索所有子目錄只有一個級別,並排除數組中的子目錄列表...

如果我手動輸入,它將是:

find /var/www/* \( -path '*/cgi-bin' -o -path '*/tmp' -o -path '*/test' -o -path '*/html' -o -path '*/icons' \) -prune -type d

我是否應該想循環到每個子目錄並做同樣的事情......我希望你明白我的觀點。

所以我想要做的事情似乎有可能,但我有點問題, printf“,%s”不喜歡我使用所有這些find -path或-o選項。 這是否意味着我必須再次使用eval?

我試圖在這里使用bash的功能,而不是一些for循環。 任何建設性的意見將不勝感激。

嘗試類似的東西

find /var/www/* \( -path "${Iggy[0]}" $(printf -- '-o -path "*%s" ' "${Iggy[@]:1}") \) -prune -type d

看看會發生什么。

編輯:在示例中將前導*添加到每個路徑。

這是基於您的描述的完整解決方案。

#!/usr/bin/env bash
basepath="/home/adesso/baldar"
ignore=("/cgi-bin" "/tmp" "/test" "/html" "/icons")

find "${basepath}" -maxdepth 1 -not \( -path "*${ignore[0]}" $(printf -- '-o -path "*%s" ' "${ignore[@]:1}") \) -not -path "${basepath}" -type d

$ basepath的子目錄,不包括$ ignore中列出的那些,假設$ ignore中至少有兩個(修復並不難)。

當給定包含文字空格的目錄名時,現有答案是錯誤的。 安全可靠的做法是使用循環。 如果你關心的是利用“bash的力量” - 我認為一個強大的解決方案比一個有缺陷的解決方案更強大。 :)

BasePath="/home/adesso/baldar"
declare -a Iggy=( "/cgi-bin" "/tmp" "/test" "/html" "/icons" )

find_cmd=( find "$BasePath" '(' )

## This is the conventional approach:
# for x in "${Iggy[@]}"; do
#  find_cmd+=( -path "*${x}" -o )
#done

## This is the unconventional, only-barely-safe approach
## ...used only to avoid looping:
printf -v find_cmd_str ' -path "*"%q -o ' "${Iggy[@]}"
find_cmd_str=${find_cmd_str%" -o "}
eval "find_cmd+=( $find_cmd_str )"

find_cmd=( "${find_cmd[@]:0:${#find_cmd[@]} - 1}"

# and add the suffix
find_cmd+=( ')' -prune -type d )

# ...finally, to run the command:
"${find_cmd[@]}"
FIND="$(which find --skip-alias)"
BasePath="/home/adesso/baldar"
Iggy=( "/cgi-bin" 
    "/tmp" 
    "/test" 
    "/html" 
    "/icons" )
SubDomains=( $(${FIND} ${BasePath}/* -maxdepth 0 -not \( -path "*${Iggy[0]}" $(printf -- '-o -path "*%s" ' "${Iggy[@]:1}") \) -type d) )
echo ${SubDomains[1]}

感謝@Sorpigal我有一個解決方案。 我最終嵌套了命令替換,因此我可以在cron中使用該腳本,最后在所有部分中添加了Array定義。 已知問題是名稱中包含空格的目錄。 然而這已經解決了,所以試圖保持簡單,我認為這回答了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM