2014-03-07 61 views
-1

我試圖回答這個問題的建議:Test whether a glob has any matches in bash測試一個水珠是否在bash任何匹配 - 與變量

if test -n "$(find . -maxdepth 1 -name 'glob*' -print -quit)" 
then 
    echo found 
else 
    echo not found 
fi 

不過,我與變量的腳本這樣做。

#!/bin/sh 
directory=~/nd 
glob="*12*.idx" 
cd $directory 
if test -n "$(find . -maxdepth 1 -name \"$glob\" -print -quit)" 
then 
    echo found 
else 
    echo not found 
fi 

運行腳本給我:

not found 

但在運行命令自己

find . -maxdepth 1 -name "*12*.idx" -print -quit 

給我一個結果

./notes_archive_2012.idx 

這是一個引用的問題?

回答

1

是的,這是一個引用問題。 $(...)內不應該引用引號。試想一下:

test -n "$(find . -maxdepth 1 -name \"$glob\" -print -quit)" # Wrong 

在上面的表格中,參數-namefind看到起始和文字雙引號結束。它只會匹配文件名稱,如果文件名稱本身開始並以雙引號結尾。

下你想要做什麼:

test -n "$(find . -maxdepth 1 -name "$glob" -print -quit)" # Right 

man bash

當使用$(命令)形式,括號中的所有字符 使 了命令;沒有人專門處理。

換句話說,如果您想在$(...)的命令中使用雙引號,只需使用雙引號。應寫入$(...)中的命令,就像它自己在命令行上輸入一樣。

+0

非常好,謝謝。 :) –

0

您可以在沒有外部命令的情況下執行此操作。一種方法是濫用for循環了一下:

# Use the loop as a context for expanding the glob, not actually iterating 
# over the results. 
for f in $glob; do 
    if [[ -f "$f" ]]; then 
     echo found 
    else 
     echo not found 
    fi 
    break 
done 

您也可以使用數組:

files=($glob) 
if [[ -f "${files[0]}" ]]; then 
    echo found 
else 
    echo not found 
fi 
0

發現工程存在的本地文件,但不能用於遠程文件或任何其他時刻的文件,本地不存在。有時你想檢查一個任意的匹配,並且該模式是在一個字符串中。

bash支持[[ "$string" == shellmatch* ]][[ "$string" =~ ^regexmatch.* ]]但不支持任何形式的[[ "$string" == "$shellmatch" ]]其中match參數是一個字符串。我還沒有找到任何方法來欺騙bash來處理一個字符串,而不是寫出正確格式化的新shell腳本,我不相信空格或]括號會被正確支持。

Rich’s sh (POSIX shell) tricks是一個單線程,與大多數POSIX shell使用不超過案件和一些聰明的引用。經測試與bash合作,sh。經測試不能使用zsh。

fnmatch() { case "$2" in $1) return 0 ;; *) return 1 ;; esac ; } 

我用這個變種,所以我可以空白,代表所有

fnmatch() { [ -z "$1" ] && return 0; case "$2" in $1) return 0 ;; esac; return 1 ; } 

Examples:

fnmatch 'ab \?def' 'ab ?def' && echo 'matched' # \ supported 
fnmatch 'ab ?def' 'ab cdef'  && echo 'matched' # ? supported 
fnmatch 'ab [cd]def' 'ab cdef' && echo 'matched' # [] supported 
fnmatch 'ab {c,d}def' 'ab cdef' && echo 'matched' # case does not support brace expansion 
fnmatch 'ab c*' 'ab cdef'  && echo 'matched' # space supported 
fnmatch 'ab) c*' 'ab) cdef'  && echo 'matched' #) supported, does not interfere with case 
相關問題