GNU/Linux >> Linux の 問題 >  >> Linux

bashで(コマンド引数のように)引用符で文字列を分割する方法は?

最も簡単な解決策は、引用符で囲まれた引数の配列を作成して、必要に応じてループするか、コマンドに直接渡すことです。

eval "array=($string)"

for arg in "${array[@]}"; do echo "$arg"; done   

追記eval を使わないもっと簡単な方法を見つけたらコメントしてください .

編集:

@Hubbitus の回答に基づいて、完全にサニタイズされ、適切に引用されたバージョンがあります。注:これはやり過ぎであり、実際には、ほとんどの句読点の前に二重引用符または単一引用符で囲まれたセクションに追加のバックスラッシュが残りますが、攻撃に対しては無敵です。

declare -a "array=($( echo "$string" | sed 's/[][`[email protected]#$%^&*():;<>.,?/\|{}=+-]/\\&/g' ))"

興味のある読者が適切と思われるように修正してください http://ideone.com/FUTHhj


David Postillの答えを見たとき、「もっと簡単な解決策があるに違いない」と思いました。いくつかの実験の後、私は次の作品を見つけました:-

string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
echo $string
eval 'for word in '$string'; do echo $word; done'

eval のため、これは機能します 行を展開します (引用符を削除して string を展開します) ) 結果の行 (インラインの回答) を実行する前に:

for word in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $word; done

同じ行に展開する別の方法は次のとおりです:

eval "for word in $string; do echo \$word; done"

こちら string は二重引用符内で展開されますが、$ word になるようにエスケープする必要があります 行が実行される前に展開されません (他の形式では、一重引用符を使用しても同じ効果があります)。結果は次のとおりです:-

[~/]$ string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
[~/]$ echo $string
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
[~/]$ eval 'for word in '$string'; do echo $word; done'
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
[~/]$ eval "for word in $string; do echo \$word; done"
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

どうすればいいですか?

$ for l in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $l; done
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

文字列が bash の場合はどうすればよいですか 変数?

bash を使用した単純なアプローチ 文字列トークナイザーは、引用符の外側のスペースだけでなくすべてのスペースで分割されるため、機能しません:

[email protected] /f/test
$ cat ./test.sh
#! /bin/bash
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
for word in $string; do echo "$word"; done

[email protected] /f/test
$ ./test.sh
"aString
that
may
haveSpaces
IN
IT"
bar
foo
"bamboo"
"bam
boo"

これを回避するために、次のシェル スクリプト (splitstring.sh) は 1 つの方法を示しています。

#! /bin/bash 
string=$(cat <<'EOF'
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo" 
EOF
)
echo Source String: "$string"
results=()
result=''
inside=''
for (( i=0 ; i<${#string} ; i++ )) ; do
    char=${string:i:1}
    if [[ $inside ]] ; then
        if [[ $char == \\ ]] ; then
            if [[ $inside=='"' && ${string:i+1:1} == '"' ]] ; then
                let i++
                char=$inside
            fi
        elif [[ $char == $inside ]] ; then
            inside=''
        fi
    else
        if [[ $char == ["'"'"'] ]] ; then
            inside=$char
        elif [[ $char == ' ' ]] ; then
            char=''
            results+=("$result")
            result=''
        fi
    fi
    result+=$char
done
if [[ $inside ]] ; then
    echo Error parsing "$result"
    exit 1
fi

echo "Output strings:"
for r in "${results[@]}" ; do
    echo "$r" | sed "s/\"//g"
done

出力:

$ ./splitstring.sh
Source String: "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
Output strings:
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

出典:StackOverflowの回答チョロバで引用符の外にあるスペースだけで文字列を分割します。スクリプトは、質問の要件に合わせて調整されています。


Linux
  1. Bashスクリプトで文字列を分割する方法

  2. 時間コマンドでBashスクリプトの実行にかかる時間を確認する

  3. bash コマンドで CPU スパイクを作成する方法

  1. bashでファイルをファイルタイプ別にフォルダにソートする方法(「file」コマンドを使用)?

  2. bash 引数で引用符を保持する

  3. tr コマンド - 文字列 \n を実際の改行 (\n) に置き換える方法

  1. 一重引用符と二重引用符の両方を含む bash エイリアス コマンド

  2. bash:特殊文字を含むコマンドライン引数を渡す方法

  3. bashコマンド文字列の逐語的な文字を確認するにはどうすればよいですか?