Bash

包含“*”(星號)的數組元素的自動擴展問題

  • September 29, 2012

我正在嘗試為我編寫一個find腳本,該腳本以後應該能夠讀取要從外部文件中排除的目錄列表。雖然我可以自己完成那部分,但令人討厭的數組擴展使任務變得困難。首先,一些“準備工作”以獲得合適的範例目錄樹:

$ mkdir tmp && cd tmp
$ mkdir excl1_dirx excl2_dirx excl3_dirx
$ touch excl1_dirx/dummy1.txt excl2_dirx/dummy2.txt excl3_dirx/dummy3.txt
$ mkdir excl1_diry excl2_diry excl3_diry
$ touch excl1_diry/dummy4.txt excl2_diry/dummy5.txt excl3_diry/dummy6.txt
$ touch dummy00.txt dummy01.txt

如果腳本有效,則只有dummy00.txt並且dummy01.txt可能會顯示。

#!/bin/bash
excl_d=("excl*_dirx" "excl*_diry")

find_str=" . -type f ! ( "

for ((i=0 ; i<$((${#excl_d[*]})) ; i++)); do
  if [[ $i > 0 ]]; then
    find_str+=" -o "
  fi

 find_str+=" -path \"./${excl_d[i]}/*\""
done

find_str+=" )"

# this is just for debugging
echo "[debug] value of str = find $find_str"

find $find_str

首先:為什麼在“ done”之前的行中(看似)如此復雜?嗯,bash有時喜歡通過做他們不期望的事情來惹惱使用者。沒有這些引號,它將擴展每個數組元素;egexcl*_dirx將成為excl1 dirx excl2 dirx excl3 dirx,這(顯然)打破了-path界限!儘管我在每個數組元素中使用了一對雙引號,這實際上是為了防止 bash 進行擴展惡作劇!

然而,最好的還沒有到來:倒數第二行 - 當( )轉義到時\( \)- 將在 shell 中正常工作,但不能在獨立腳本中工作。即使它不會拋出任何錯誤,但後一個實現的結果將是錯誤的。

我已經嘗試了各種單引號和雙引號的組合

find_str+=" -path \"./${excl_d[i]}/*\""

行,但我只是無法讓它工作,即使它在顯示為倒數第二行時看起來絕對完美。似乎bash內部對待我的轉義引號\"與非轉義引號不同。啊,引號內的引號幾乎無處不在,由於某種原因,在使用該運算符時會被過濾掉+=

我不僅在尋找這種行為的解釋,而且還在尋找如何在獨立腳本中使其工作的解決方案。這一定是我犯的一個愚蠢的錯誤。:-/

這裡的問題是這find_str是一個字元串,然後將其用作字元串列表。jw013 的評論是正確的,請閱讀我正在嘗試將命令放入變數中,但複雜的情況總是失敗!. 您沒有將整個命令放在一個變數中,但是一旦您嘗試將多個單詞填充到字元串變數中,就會出現問題。

在 Bourne/POSIX shell 中,這是必要的邪惡。但是在 ksh/bash/zsh 中,有一個更好的方法:使用數組。

#!/bin/bash
excl_d=("excl*_dirx" "excl*_diry")
find_str=( . -type f \! \( )
for ((i=0 ; i<$((${#excl_d[*]})) ; i++)); do
  if [[ $i > 0 ]]; then
    find_str+=( -o )
  fi
 find_str+=( -path "./${excl_d[i]}/*" )
done
find_str+=( \) )
find "$find_str[@]}"

有一種更簡單的方式來表達這樣的過濾器。

#!/bin/bash
exclude_patterns=("excl*_dirx" "excl*_diry")
exclude_args=()
while [[ ${#exclude_patterns} -gt 0 ]]; do
 exclude_args+=( -path "./${exclude_patterns[1]}/*" -prune -o )
 shift exclude_patterns
done
find "${exclude_args[@]}" -type f

引用自:https://unix.stackexchange.com/questions/49405