Bashスクリプトのエスケープスペースは機能しません。

Bashスクリプトのエスケープスペースは機能しません。

私が試したことは何も機能しませんでした。以下のスクリプトでgrep to array行を見てください。逃げても役に立たないようです。しかし、静的に割り当てられた配列を作成しても大丈夫です。

たとえば、

files=(somefile.txt
some\ other\ file.pdf
"yet another file.txt")

これはうまくいきません:

#!/bin/bash
find . -name "$1" |
(
        cat - > /tmp/names
        file -N --mime-type --files-from /tmp/names
) |
(
        cat - > /tmp/mimes
#       files=("$(grep -o '^[^:]*' /tmp/mimes)") #one element array
#       files=($(grep -o '^[^:]*' /tmp/mimes)) #files with spaces end up split in to several elements
#       files=($(grep -o '^[^:]*' /tmp/mimes | sed 's/ /\\ /g')) #same but with \ terminated strings
        files=($(grep -o '^[^:]*' /tmp/mimes | cat <(echo '"') - <(echo '"')))
        mimes=($(grep -o '[^:]*$' /tmp/mimes))

        total=${#files[*]}
        for (( i=0; i<=$(( $total -1 )); i++ ))
                do
                echo Mime: "${mimes[$i]}" File: "${files[$i]}"
        done
        printf "$i\n"
)

編集する: 説明

/tmp/mimes ファイルには以下が含まれます。

./New Text.txt: text/plain

":"前のすべてを得るためにgrep

grep -o '^[^:]*' /tmp/mimes

出力: ./New Text.txt

この出力を配列に入れたいのですが空白があるので、sedを使用して空白をエスケープします。

files=($(grep -o '^[^:]*' /tmp/mimes | sed 's/ /\\ /g'))

これはうまくいきません。私は files[0] = "./New\" と files[1] = "Text.txt" で終わります。

私の質問は、エスケープスペースが機能しない理由です。

私がするなら:

files=(./New\ Text.txt)

動作しますが、なぜ files[0] = "./New Text.txt" エスケープを手動で実行すると動作しますが、grep および sed の出力の場合は動作しません。配列を作成する動作が一貫性がないようです。

ベストアンサー1

改行で区切られたファイル名が必要な場合は、IFSを次のように設定し$'\n'てグローブをオフにします。

set -f
IFS=$'\n' files=($(grep -o '^[^:]*' /tmp/mimes))
set +f

ファイル名に改行(名前を抽出するためにgrepを使用した方法で破損したコロンに加えて)が含まれていると、中断されます。

おすすめ記事