バッシュ、ksh、zsh

バッシュ、ksh、zsh

たとえば。{a..c}{1..3}a1 a2 a3 b1 b2 b3 c1 c2 c3

印刷したいのですが、a1 b1 c1 a2 b2 c2 a3 b3 c3同様の方法がありますか?最も簡単な方法は何ですか?

答え1

次のことができます。

$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3

次に、シェルに以下を評価するように指示します。

echo {a..c}1 {a..c}2 {a..c}3

答え2

この特別なケースでは、与えられたオプションスティーブン・チャジェラスそれが一番です。

一方、このオプションはより複雑なものに拡張するとうまく機能しません。したがって、次の方法で同じ結果を得ることができます。

$ printf '%s\0' {a..c}{1..3} | sort -zk 1.2,1.2 | tr '\0' ' '

返品:

a1 b1 c1 a2 b2 c2 a3 b3 c3

少し汚れているように見えますが、今度は多くの順序を制御することができ、上記のコマンドで2文字しか変更できません。

$ echo {a..b}{1..2}{a..b}{1..2}

これは次のように拡張されます。

a1a1 a1a2 a1b1 a1b2 a2a1 a2a2 a2b1 a2b2 b1a1 b1a2 b1b1 b1b2 b2a1 b2a2 b2b1 b2b2

2番目の拡張のすべての内容が欲しいとしましょう12

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.2 | tr '\0' ' '
a1a1 a1a2 a1b1 a1b2 b1a1 b1a2 b1b1 b1b2 a2a1 a2a2 a2b1 a2b2 b2a1 b2a2 b2b1 b2b2

3番目の拡張のすべての内容が欲しいとしましょうab

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.3,1.3 | tr '\0' ' '
a1a1 a1a2 a2a1 a2a2 b1a1 b1a2 b2a1 b2a2 a1b1 a1b2 a2b1 a2b2 b1b1 b1b2 b2b1 b2b2

4番目の拡張のすべての内容が欲しいとしましょ12

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.4,1.4 | tr '\0' ' '
a1a1 a1b1 a2a1 a2b1 b1a1 b1b1 b2a1 b2b1 a1a2 a1b2 a2a2 a2b2 b1a2 b1b2 b2a2 b2b2

1a途中でthen 1b、then 2a、thenがすべて欲しいとしましょう2b

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.3 | tr '\0' ' '
a1a1 a1a2 b1a1 b1a2 a1b1 a1b2 b1b1 b1b2 a2a1 a2a2 b2a1 b2a2 a2b1 a2b2 b2b1 b2b2

rたとえば、最後のコマンドに1つを追加すると、上記の拡張の順序を簡単に置き換えることができます。

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -rzk 1.2,1.3 | tr '\0' ' '
b2b2 b2b1 a2b2 a2b1 b2a2 b2a1 a2a2 a2a1 b1b2 b1b1 a1b2 a1b1 b1a2 b1a1 a1a2 a1a1

Note_1:通常、最後の拡張が引数リストとして使用されている場合は、末尾のスペースは問題になりませんが、それらを削除するには、上記のコマンドに を追加できます。| sed 's/ $//';または、| sed 's/ $/\n/'末尾のスペースを次に変更します。newline

ノート2:上記の例では、2つの要素のサブセットを使用しました(例:{a,b}そして{1,2}) 概念証明を簡素化するために、有限長のサブセットを使用することができ、対応するコマンドは比較できます。

答え3

バッシュ、ksh、zsh

(bash、ksh、zsh)で動作する1行のコードです(すべてのシェルが「中括弧の拡張」を逆の順序で実行できるわけではありません)。

$ echo {3..1}{c..a} | rev
a1 b1 c1 a2 b2 c2 a3 b3 c3

使用された代替案はeval次のとおりです(まだbash、ksh、zsh、おそらくより不思議な仕事で動作します)。

$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3

何が起こっているのかを確認するには、次のようevalに置き換えますecho

$ echo echo '{a..c}'{1..3}
echo {a..c}1 {a..c}2 {a..c}3

(評価拡張後)実行されるコマンドは、実際にはecho {a..c}1 {a..c}2 {a..c}3必要に応じて拡張できます。

すべての殻

「中括弧拡張」を持たない複数のシェルがあるため、「すべてのシェル」と一緒に使用することはできません。ループが必要です(末尾のスペースを含む)。

$ for i in 1 2 3; do for j in a b c; do printf "%s%s " "$j" "$i"; done; done; echo
a1 b1 c1 a2 b2 c2 a3 b3 c3 

後にスペースを追加しないでください。

s=""
for i in 1 2 3; do
    for j in a b c; do
        printf "%s%s%s" "$s" "$j" "$i"
        s=" "
    done
done
echo

印刷

a1 b1 c1 a2 b2 c2 a3 b3 c3

多くの値を使用してこれを行う必要がある場合は、中括弧の拡張などの機能を使用して数値リストを生成する必要があります$(seq 10)。また、seqは文字リストを生成できないため、生成された数字をasciiに変換する必要があります。

s=""
for i in $(seq 4); do
    for j in $(seq 5); do
        printf "%s\\$(printf %03o $((96+j)))%s" "$s" "$i"
        s=" "
    done
done
echo

印刷:

a1 b1 c1 d1 e1 a2 b2 c2 d2 e2 a3 b3 c3 d3 e3 a4 b4 c4 d4 e4

答え4

ループを使用してください。

for n in {1..3}; do printf '%s\n' {a..c}"$n"; done

これは最初の拡張を繰り返し、次に2番目の拡張を使用して各文字を拡張します。

すべての出力を1行に表示する必要がある場合は、以下を削除できます\n

for n in {1..3}; do printf '%s ' {a..c}"$n"; done

これは末尾の改行を提供しませんが、それをコマンドまたは変数に渡す場合は問題になりません。

関連情報