質問
私は、個々のアイテムでスペースを入れずに、同じ長さの二つのリストを持っています:
list1="a b c"
list2="1 2 3"
私はなど、2とB、1とのペアリング、並行してこれら二つのリストを反復処理したい:ます。
a 1
b 2
c 3
私はバッシュ/ kshの配列は使用できませんので、現代のポータブルBourneシェルをサポートしようとしています。 AWKに砲撃してピンチに受け入れられるだろうが、可能であれば私はむしろ純粋なSHでこれを維持すると思います。
あなたが提供することができます任意のポインタをありがとう!
解決
これは少しハックですが、仕事をしていません。
#!/bin/sh
list1="1 2 3"
list2="a b c"
while [ -n "$list1" ]
do
head1=`echo "$list1" | cut -d ' ' -f 1`
list1=`echo "$list1" | sed 's/[^ ]* *\(.*\)$/\1/'`
head2=`echo "$list2" | cut -d ' ' -f 1`
list2=`echo "$list2" | sed 's/[^ ]* *\(.*\)$/\1/'`
echo $head1 $head2
done
他のヒント
おそらく移植性がありませんが、読みやすいですし、他の誰かがそれに便利...
見つけるかもしれませんlist1="a b c"
list2="1 2 3"
array1=($list1)
array2=($list2)
count=${#array1[@]}
for i in `seq 1 $count`
do
echo ${array1[$i-1]} ${array2[$i-1]}
done
これはかなりきれいな解決策になるはずですが、あなたはbash
のプロセスsubstitionを使用しない限り、それは一時ファイルを使用する必要があります。それは各反復上cut
とsed
を呼び出すよりも良いか悪いかどうかは分かりません。
#!/bin/sh
list1="1 2 3"
list2="a b c"
echo $list1 | sed 's/ /\n/g' > /tmp/a.$$
echo $list2 | sed 's/ /\n/g' > /tmp/b.$$
paste /tmp/a.$$ /tmp/b.$$ | while read item1 item2; do
echo $item1 - $item2
done
rm /tmp/a.$$
rm /tmp/b.$$
これはポータブルでも二つ以上のリストで動作する必要があります:
#!/bin/sh
x="1 2 3 4 5"
y="a b c d e"
z="A B C D E"
while
read current_x x <<EOF
$x
EOF
read current_y y <<EOF
$y
EOF
read current_z z <<EOF
$z
EOF
[ -n "$current_x" ]
do
echo "x=$current_x y=$current_y z=$current_z"
done
あまりにも、位置paramersの作品を使用しました。 「 - 」リスト要素がで始めることはできませんのでご注意ください。それ以外の場合は、 "設定" 失敗します。
#!/bin/sh
x="1 2 3 4 5"
y="a b c d e"
z="A B C D E"
while
[ -n "$x" ]
do
set $x
current_x=$1
shift
x="$*"
set $y
current_y=$1
shift
y="$*"
set $z
current_z=$1
shift
z="$*"
echo "x=$current_x y=$current_y z=$current_z"
done
NEVERMINDは、SAW "ボーン" とは、 "AGAINボーン" と思いました。それは尋ねた質問への答え誰かのために有用であることが、はっきりしない場合がありますので、ここではこれを残して、申し訳ありません!
-
このは(それが優雅にサイズが異なるリストを処理しません)、いくつかの欠点がありますが、それはあなたが与えた例のために働くます:
#!/bin/bash
list1="a b c"
list2="1 2 3"
c=0
for i in $list1
do
l1[$c]=$i
c=$(($c+1))
done
c=0
for i in $list2
do
echo ${l1[$c]} $i
c=$(($c+1))
done
そこのawkやカットなどの一般的なUNIXツールを使用して、より優雅な方法がありますが、上記の要求に応じて、純粋な-bashの実装です。
受け入れ答えにコメント、それはLinuxまたはSolarisのいずれかで私のために動作しませんでした、問題はsedのための正規表現で\ S文字クラスのショートカットでした。私は[^]でそれを置き換え、それが働いた:
#!/bin/sh
list1="1 2 3"
list2="a b c"
while [ -n "$list1" ]
do
head1=`echo "$list1" | cut -d ' ' -f 1`
list1=`echo "$list1" | sed 's/[^ ]* *\(.*\)$/\1/'`
head2=`echo "$list2" | cut -d ' ' -f 1`
list2=`echo "$list2" | sed 's/[^ ]* *\(.*\)$/\1/'`
echo $head1 $head2
done
配列を使用していないソリューション:
list1="aaa1 aaa2 aaa3"
list2="bbb1 bbb2 bbb3"
tmpfile1=$( mktemp /tmp/list.XXXXXXXXXX ) || exit 1
tmpfile2=$( mktemp /tmp/list.XXXXXXXXXX ) || exit 1
echo $list1 | tr ' ' '\n' > $tmpfile1
echo $list2 | tr ' ' '\n' > $tmpfile2
paste $tmpfile1 $tmpfile2
rm --force $tmpfile1 $tmpfile2
1つのライナーとして:
list2="1 2 3";
list1="a b c";
for i in $list1; do
x=`expr index "$list2" " "`;
[ $x -eq 0 ] && j=$list2 || j=${list2:0:$x};
list2=${list2:$x};
echo "$i $j";
done
$ list1="1 2 3"
$ list2="a b c"
$ echo "$list1 $list2" | awk '{n=NF/2; for (i=1;i<=n;i++) print $i,$(n+i) }'
1 a
2 b
3 c
私は、sedのベースの答えに取り組んでいました。
:しかし、さらに調査すると、それは私が頭と尾に基づくソリューションで行くことを許され、リスト内の項目は改行ではなくスペースで区切ったことが判明しましたoriginal_revs="$(cd original && git rev-parse --all)" &&
working_revs="$(cd working && git rev-parse --all)" &&
while test -n "$original_revs"; do
original_commit="$(echo "$original_revs" | head -n 1)" &&
working_commit="$(echo "$working_revs" | head -n 1)" &&
original_revs="$(echo "$original_revs" | tail -n +2)" &&
working_revs="$(echo "$working_revs" | tail -n +2)" &&
...
done
私は、誰かがこの問題の変種に遭遇しただけの場合にこれを掲示していますが、私は掲載され問題に基づいて受け入れ答えを授与しています。