Language detail: Bash
|
number of '+' ratings |
contribution for coverage |
Unsolved challenges
- echoクライアント (Nested Flatten)
- tailの実装 (Nested Flatten)
- lessの実装 (Nested Flatten)
- コード圧縮 (Nested Flatten)
- クリップボードへの転送 (Nested Flatten)
codes
$ compact_number_list 1 3 4 5 6 12 13 15 20 25 26 27 [ 1 [ 3 6 ] 12 13 [ 15 25 5 ] 26 27 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function compact_number_list() {
echo -n '[ '
while (($# > 0));do
if (($# >= 3)) && (($2 - $1 == $3 - $2));then
local d=$(($2 - $1))
echo -n "[ $1 "
shift 2
while (($# >= 2)) && (($2 - $1 == d));do
shift
done
echo -n "$1 "
((d != 1)) && echo -n "$d "
echo -n '] '
else
echo -n "$1 "
fi
shift
done
echo ']'
}
|
sortを使いawkを使わない解。bashとdashで動作確認。
1、3、4、5行目にはタブ文字が含まれています。
1 2 3 4 5 6 | IFS=' '
read -r id forename surname age
echo "$id $surname $forename $age"
sort -n -t ' ' | while read -r id forename surname age;do
echo "$id $surname $forename $((age + 1))"
done
|
配列の添字が冗長だったので微修正します。
1 2 3 4 5 6 7 8 | n=1
for ((i = 0; i < 100; i++));do
echo $n
ary[n*2]=1
ary[n*3]=1
ary[n*5]=1
while [ "${ary[++n]}" != 1 ];do :;done
done
|
アプローチとしては#7638と同じでしょうか。配列。
1 2 3 4 5 6 7 8 | n=1
for ((i = 0; i < 100; i++));do
echo $n
ary[$((n*2))]=1
ary[$((n*3))]=1
ary[$((n*5))]=1
while [ "${ary[$((++n))]}" != 1 ];do :;done
done
|
bashやPOSIX-shでは、外部コマンドや内部コマンドよりシェル関数が優先して呼ばれます。いっぽう、commandコマンドを使うことにより、シェル関数を省いて外部コマンドや内部コマンドを呼べます。
これを組み合わせると、下のコードのようにして、外部コマンドをシェル関数でフックできます。
ただし、シェル関数はこの方法ではフックできません。
1 2 3 4 5 6 7 8 9 10 11 12 13 | ls() {
# before
echo '***** start *****'
# command itself
command ls "$@"
local result=$?
# after
echo '***** end *****'
return $result
}
|
#7614の訂正にしたがって簡略化してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #!/bin/bash
while getopts 'oqd:*' opt;do
case "$opt" in
o) opt_o=ON ;;
q) opt_q=ON ;;
d) opt_d=$OPTARG
[[ $opt_d == [012] ]] || exit 1
;;
esac
done
shift $((OPTIND - 1))
[ -z "$opt_o" ] && exit 1
[ $# = 0 ] && exit 1
echo "[オプション情報]
o(output): ON
q(quote): ${opt_q:-OFF}
d(debug): ${opt_d:-}
[パラメータ情報]
指定数: $#"
i=0
for e in "$@";do
echo "$((++i)): $e"
shift
done
|
pure bashで内蔵コマンドgetoptsを使いました。
起動例の-sはコマンドじゃなくて引数扱い、と解釈したために、その部分がBKっぽくなっています。
あと、-oは必須ということで、そこの出力は手抜きしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #!/bin/bash
OPTERR=0
args=()
nargs=0
opt_o=OFF
opt_q=OFF
opt_d=''
while [ $# != 0 ];do
oprind_orig=$OPTIND
while getopts 'oqd:*' opt;do
case "$opt" in
o) opt_o=ON
;;
q) opt_q=ON
;;
d) opt_d=$OPTARG
[[ $opt_d == [012] ]] || exit 1
;;
\?) [[ ! ${!OPTIND} == -* ]] && ((OPTIND--))
break
;;
esac
done
shift $((OPTIND - 1))
OPTIND=1
[ $# != 0 ] && args[$((nargs++))]=$1
shift
done
[ "$opt_o" = OFF ] && exit 1
((nargs)) || exit 1
echo "[オプション情報]
o(output): ON
q(quote): $opt_q
d(debug): $opt_d
[パラメータ情報]
指定数: $nargs"
for ((i = 0; i < nargs; i++));do
echo "$((i + 1)): ${args[$i]}"
done
|
LL Futureゴルフコースありがとうございました。楽しませていただきました。
今回も無駄にpure bashで書いてみます。
enable-net-redirectionsつきでビルドされたbashで、UTF-8のソース前提です。
# 同じurlパラメータからだと、サーバーから既出だとツッコまれますね、当然ながら
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | function urlencode() { # just workaround
local s=$1
s=${s// /+}
echo "${s//
/%0A}"
}
function http_post() {
local host=$1
local path=$2
local post_data=$3
local LANG=C
exec 3<> "/dev/tcp/$host/80"
(
echo -e "POST $path HTTP/1.0\r"
echo -e "Host: $host\r"
echo -e "Content-Length: ${#post_data}\r"
echo -e 'Content-Type: application/x-www-form-urlencoded; charset=utf-8\r'
echo -e '\r'
echo "$post_data"
) >&3
local s
read -d '' s <&3
echo "$s"
exec 3>&-
exec 3<&-
}
function trackback() {
local host=$1
local path=$2
local title=$(urlencode "$3")
local url=$4
local blog_name=$(urlencode "$5")
local excerpt
read -d '' excerpt
excerpt=$(urlencode "$excerpt")
http_post "$host" "$path" \
"title=$title&url=$url&blog_name=$blog_name&excerpt=$excerpt"
}
trackback 'll.jus.or.jp' '/2008/blog/archives/38/trackback' \
'LL Future参加' 'http://ja.doukaku.org/207/' 'LL Future Hole 9' <<'__EOT__'
LL Futureに行ってきました!
楽しかった! 自分の回答がスクリーンに出た><
__EOT__
|
内蔵コマンドのみのpure bashで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function remove_comment() {
local str=$1
while [[ $str == */\** ]];do
echo -n ${str%%/\**}
str=${str#*/\*}
if [[ $str == *\*/* ]];then
str=${str#*\*/}
else
str=''
fi
done
echo $str
}
remove_comment 'AAA'
remove_comment 'AAA/*BBB*/'
remove_comment 'AAA/*BBB'
remove_comment 'AAA/*BBB*/CCC'
remove_comment 'AAA/*BBB/*CCC*/DDD*/EEE'
remove_comment 'AAA/a//*BB*B**/CCC'
|
内蔵コマンドのみのpure bashで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | shopt -s extglob
declare -i age
function readRecord() {
local n=$1
local s d
read -n 12 s
family_name[$n]=${s%%+( )}
read -n 12 s
first_name[$n]=${s%%+( )}
read -n 1 sex[$n]
read -n 3 age[$n]
read -n 4 year[$n]
read -n 2 mon[$n]
for ((d = 0; d < 31; d++));do
eval read -n 2 date_$d[$n]
read -n 500 s
eval "breakfast_$d[$n]='${s%%+( )}'"
read -n 500 s
eval "lunch$d[$n]='${s%%+( )}'"
read -n 500 s
eval "dinner_$d[$n]='${s%%+( )}'"
done
}
for ((i = 0; i < 500; i++));do
readRecord $i
done < data.txt
|
上下左右のみの単純実装です。
1 2 3 4 5 6 7 8 9 10 11 | dx=(1 0 -1 0)
dy=(0 1 0 -1)
x=0
y=0
i=0
while :;do
echo $((i++)) $x $y
((r = RANDOM % 4))
((x += dx[r]))
((y += dy[r]))
done
|
bashで、exportされてないシェル変数を避けて環境変数の一覧を表示する方法には「printenv」「env」「export -p」があります。このうちexportはbash内蔵コマンドです。
特定のキーから環境変数の値を得るには、printenvに環境変数名を与えます。
蛇足として、内蔵コマンドだけで「printenv 変数名」相当のことをするコマンド(関数)を定義してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 環境変数一覧は以下のどれかで
printenv
env
export -p
# キーから値を得るには、printenvで
prinetnv 'HOME'
# printenvは外部コマンドだからという方には、pure bashで
myprintenv1() {
local name=$1
local a b str
export -p | while read a b str;do
if [ ${str%%=*} = "$name" ];then
str=${str#*=\"}
echo ${str%\"}
break
fi
done
}
|
お題のShowPrice.iniに合わせた回答です。
1 2 3 4 5 | showPrice() {
local ITEM_NAME ITEM_COST
. ShowPrice.ini
echo "「$ITEM_NAME」は$((ITEM_COST + ITEM_COST * 5 / 100))円(税込み)"
}
|
仕様2を満たしていませんでした。
修正と、ついでに1引数に対応。
1 2 3 4 5 6 7 8 | DateEx() {
[ -z "$2" ] && set '' $1
if [[ $2 == -* ]];then
date -d "$1 ${2:1} seconds ago"
else
date -d "$1 $2 seconds"
fi
}
|
1 2 3 | DateEx() {
date -d "$1 $2 seconds"
}
|
空気を読まずにネタ回答。
設問からは外れてないはず。
1 2 3 4 5 6 7 8 9 10 11 12 13 | stty raw
tput clear
for ((i=$1*2-1;i>0;i--));do
for ((j=0;j++<i;));do
echo -n \*
tput cub1
tput cud1
done
tput cuf1
tput cuu $((--i))
done
tput cud $1
stty cooked
|
pure bash。86B。
1 2 3 4 | while ((i++<$1**2));do
echo -n \*
((++j>m))&&echo&&((j=0,i<($1+1)*$1/2?m++:m--))
done
|
pure bashで正攻法。
引数→標準出力。インデントを削って108B。
1 2 3 4 5 6 7 | n=$1
set 0 k M G T
while [ $n -gt 999 -a -n "$2" ];do
shift
((m=n/100%10,n=n/1000))
done
echo $n${m:+.$m$1}
|
cal 使うといいんじゃないですかねぇ。
1 2 3 4 5 6 7 8 9 10 11 | eval `date '+y=%Y;m=$((%-m+(%e>13)))'`
for i in `seq $y 2013`;do
for j in `seq $m 12`;do
if [ `cal $j $i|awk '$6==13&&$_=$6'` ];then
c=$((c+1))
printf $i-%02d-13\\n $j
fi
done
m=1
done
echo $c
|



?せんたくいた #7778() [ Bash ] Rating0/0=0.00
Rating0/0=0.00-0+
[ reply ]