對使用 find 命令找到的每個檔案執行 Bash 函數

對使用 find 命令找到的每個檔案執行 Bash 函數

我目前有這個命令,它成功地在自己的行上列印每個檔案名稱:

find . -exec echo {} \;

我試圖分割邏輯,以便find命令執行一個函數。基於這個問題我試過這個:

my_function() {
    echo $1
}
export -f my_function
find . -exec bash -c 'my_function "$@"' bash {} +

然後我得到這個輸出:

.

我也嘗試替換$@$*,但這會導致$1每個文件都沒有換行符。我想運行檢查每個文件的邏輯,所以我想$1一次只檢查一個文件。我嘗試透過空格分割輸出,for file in $1但這對於檔案名稱中包含空格的檔案不起作用。如何為命令找到的每個檔案運行 Bash 函數find

編輯:這是我正在使用的整個腳本。看起來效果很好。

# Ensures that non-csproj text files are formatted with LF line endings.
format() {
    for pathname do
        if [[ $pathname == *"git"* ]]; then
            continue
        elif [[ $pathname == *"csproj"* ]]; then
            continue
        fi
        dos2unix $pathname
    done
}
export -f format
find . -exec bash -c 'format "$@"' bash {} \;

答案1

若要在目前目錄中及其下的每個常規檔案上運行dos2unix --newline,請避免名稱包含字串的任何檔案git

find . -type f ! -name '*git*' -exec dos2unix --newline {} +

也就是說,找到名稱與模式不匹配的所有常規文件*git*,並dos2unix --newline一次盡可能大批量地運行所有這些文件。變更! -name '*git*'! -path '*git*'以避免路徑名包含該字串的任何檔案git(例如目錄中的檔案.git)。

要明確避免任何目錄,但要包含其名稱中.git可能包含的任何其他內容:git

find . -name .git -prune -o -type f -exec dos2unix --newline {} +

即使輸入使用從搜尋樹中刪除此類路徑呼叫find的任何目錄,也會停止形式。.git-prune


在編輯問題之前先回答:

您的函數僅列印出其第一個參數。點是您與 一起使用的頂級搜尋路徑find。它會通過,因為您沒有對目錄條目進行任何特定的過濾(例如,-type f僅針對常規文件,或-name,或任何其他類型的find測試)。

如果您希望函數列印其每個參數,請使用

my_function() {
    printf '%s\n' "$@"
}

讓我們printf列印每個參數並在中間換行,或者

my_function() {
    for pathname do
        printf '%s\n' "$pathname"
    done
}

它循環遍歷參數並printf為每個參數調用一次。

如果您呼叫以下函數,則預計可以正常工作

my_function "$@"

從您的內聯bash -c腳本中。擴展"$@"為給予腳本的所有參數,並單獨引用。

另一種方法是將循環移至bash -c腳本中:

for pathname do
    my_function "$pathname"
done

然後有

my_function () {
    printf '%s\n' "$1"
}

這將明確地執行您所說的操作,即為每個路徑名呼叫該函數一次。

find命令看起來像

find . -exec bash -c 'for pathname do my_function "$pathname"; done' bash {} +

或者,可以說更具可讀性,

find . -exec bash -c '
    for pathname do
        my_function "$pathname"
    done' bash {} +

順便說一句,這與

shopt -s globstar nullglob dotglob

for pathname in ./**/*; do
    my_function "$pathname"
done

.不會被處理。使用它,您不必導出您的my_function函數。

透過函數內部的循環(如本答案中的前兩段程式碼),這將被縮短為

shopt -s globstar nullglob dotglob

my_function ./**/*

相關內容