2015年06月20日

シェルスクリプトでcsvを扱う(bash)その2

前に書いたcsv処理の記事をsetコマンド使用で作成
各種条件は前記事を参照してくださいな
だいぶシェルスクリプトも組めるようになってきたなあ
でもまだまだだ

前記事はこちら
シェルスクリプトでcsvを扱う(bash)

今回は関数とIFSを変更するバージョンです

シェルスクリプト(csv2.sh)の内容
#!/bin/bash

#IFSを保存しておく
IFS_BAK=$IFS
IFS=","

NUM=0

#1行ずつ読み込む
while read STR
do
set -- $STR
hoge[$NUM]=$1
huga[$NUM]=$2

#配列に入っているか表示してみる
echo "${hoge[$NUM]} : ${huga[$NUM]}"
let NUM++
set --
done < no.csv
#IFSをもどす
IFS=$IFS_BAK
  


Posted by タカさん at 20:30Comments(0)ShellScript

2013年09月29日

パスワードハッシュ生成スクリプト(Solaris10)

暇だったのでちょっと遊びで作ってみました
Solaris10でのみ動作確認しましたが
きっちり動いてます
debianでもためしてみましたが
htpasswdコマンドが存在していて
指定してあげればLinuxでも動きます
ただしSolaris10とちがって
生成されるハッシュ値をLinuxにあわせないと
使い物にはなりませんが・・・

うまく動いたらハッシュの書き変わったshadowファイルもできあがるので
diffしてshadow.datと内容くらべてみてください
いちおうVM環境では書き換えたshadowファイルで
きっちり認証できましたw

準備するもの
本物のshadowファイルを書き換えるわけにはいかないので
shadowファイルをコピーしてshadow.datを作り
ShellScriptと同じディレクトリに置く
ファイルのオーナーもShellScriptを動かすユーザーに代えましょう
あとはShellScriptを打ち込んで動かしてみるだけ

ちょっと中の処理をいじれば
Solaris10のパスワード変更をShellScriptで
自動化してやれそうですが
こわいので出来ませんw

ShellScript名 : pwHash.sh

#!/bin/bash
#
#password hash make script
#2013.09.29

clear
WORKDIR=`pwd`
CMD=/usr/apache2/htpasswd

file_read(){
#shadow ファイルの読み込み
no=1
while read LINE
do
WORD[$no]=${LINE}
User_decision
let no++
done < $WORKDIR/shadow.dat
if [ "${user_flg}" = "0" ]; then
echo "ユーザが存在しませんでした"
exit
fi
}

field_cut(){
#fieldの切り分けとチェック
for((no2=3; no2<=9; no2++)){
FIELD[$no2]=`echo ${WORD[$no]} | cut -d : -f${no2}`
if [ "${FIELD[$no2]}" = ":" ]; then
FIELD[$no2] = ""
fi
}
}

User_decision(){
TMP_user=`echo $LINE | cut -d : -f1`
if [ "${USER}" = "${TMP_user}" ]; then
flag=1; user_flg=1
else
flag=0
fi
}

pw_replace(){
#passwordの置き換え
LINE=""; no=1
while read LINE
do
User_decision
if [ "${flag}" -eq 1 ]; then
#各fieldの切り出し
FIELD_TMP=${WORD[$no]}
NO_TMP=$no
PW=`$CMD -ndb $STR $STR | cut -d : -f2`
field_cut
WORD[$no]="$USER:$PW:${FIELD[3]}:${FIELD[4]}:${FIELD[5]}:${FIELD[6]}:${FIELD[7]}:${FIELD[8]}:${FIELD[9]}"
fi
let no++
done < $WORKDIR/shadow.dat
}

line_dsp(){
: > $WORKDIR/shadow
for((x=1; x echo ${WORD[$x]} >> $WORKDIR/shadow
}
echo "生成されたshadowファイルを表示します"
echo "push enter key"; echo
more $WORKDIR/shadow
}

echo -n "対象ユーザ名を入力してください?"
read USER; user_flg=0
file_read

echo -n "ハッシュ生成文字列を入力してください?"
read STR
pw_replace

echo "生成されたハッシュ: $PW"
echo "パスワードを置き換えます"
echo
echo "push enter key"; read stop
echo
echo "BEFORE : $FIELD_TMP"
echo "AFTER : ${WORD[$NO_TMP]}"
line_dsp

  


Posted by タカさん at 14:31Comments(0)ShellScript

2012年08月12日

シェルスクリプトでcsvを扱う(bash)その1

[ IFSをいじらないバージョン ]
※中級者向けのIFSをいじるバージョンは末尾にリンクあります

シェルスクリプトでcsvを扱う方法は
検索すれば何種類か出てくるが
sedコマンドを使ったり2次元配列もどきとawkコマンドを使ったりで
以外と複雑なものも少なくない
しかも各フィールドをそれぞれ別な配列に入れるのは
検索してもヒットしてくれない
ということで即席ではあるが
参考程度に作ってみたので残しておくことにする

とりあえず作った条件は以下のとおり
1 csvファイルを1行ずつ読み込む
2 各値をそれぞれ別な配列に入れる


csvファイルの内容(no.csv)
10,100
11,101
12,102
13,103
14,104
15,105


ShellScriptの内容(csv.sh)

#!/bin/bash

NO=0

#1行ずつ読み込む
while read STR
do
# 1.カンマはcutコマンドのオプション指定でフィールド区切り文字に指定
# 2.フィールドを指定して切り出す
hoge[$NO]=`echo $STR | cut -d , f 1`
huga[$NO]=`echo $STR | cut -d , f 2`
let NO++
done < no.csv

SUM=${#hoge[*]}

for((x=0; x<${SUM}; x++ ))
do
echo "第1フィールド:${hoge[$x]} 第2フィールド:${huga[$x]}"
done


まは配列に関しては
自分の好きな名前をつけた配列変数にいれてやればいい


実行結果

第1フィールド:10 第2フィールド:100
第1フィールド:11 第2フィールド:101
第1フィールド:12 第2フィールド:102
第1フィールド:13 第2フィールド:103
第1フィールド:14 第2フィールド:104
第1フィールド:15 第2フィールド:105


または
hoge[$NO]=`echo $STR | cut -d , f 1`
huga[$NO]=`echo $STR | cut -d , f 2`

もしこれが
10,100,1000
のようなcsvファイルの内容であったなら
huga[$NO]=`echo $STR | cut -d , f 2`
の下に
puga[$NO]=`echo $STR | cut -d , f 3`
のように配列を1行追加して用意すればよい

Shell Script中級者以上の方向け
[ IFSをいじるバージョンはこちら ]  


Posted by タカさん at 12:00Comments(0)ShellScript

2011年09月04日

シェルスクリプトの計算速度

職場の新人にシェルスクリプトの課題を出してみた
内容は下の表示例の出力をするシェルスクリプトを作成するというもの

表示例
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10



4950 + 100 = 5050

というふうに
最終的には100まで足し算をしていくシェルスクリプトだ
最初は10までで作成させようと準備していたんだけど
大量の計算を伴うと
シェルスクリプトの内容で大きく処理速度が左右されることを
新人に教えたかったので100までの計算としてみた

するとやはりシェルスクリプトに不慣れな新人は
結果は表示例と同じなのだが
速度がとても遅い以下のようなスクリプトを組んで提出してきた

#SLOW
#!/bin/bash
tmp=0
for no in {1..100}
do
ans=`expr $tmp + $no`
echo "${tmp} + ${no} = ${ans}"; tmp=$ans
done


新人のスクリプトはたしかに結果は出るが
exprで計算させているのが処理を遅くしている

#FAST
#!/bin/bash
tmp=0
for((i=1; i<=100; i++))
do
let ans+=i
echo "${tmp} + ${i} = ${ans}"; tmp=$ans
done


for文の条件を繰り返し回数の判定のみとし
計算部分は高速なlet関数を使用している
for文の条件部分は新人のスクリプトのものでも
シェルスクリプトの変数は
文字列と数値の区別がない為まったく問題はないが
計算させる為の方法に何を使用してスクリプトを組むかで
計算を苦手とするシェルスクリプトは
かなり速度に差がでるようになる
ここはシェルスクリプトの中で注意が必要な部分だ  


Posted by タカさん at 18:32Comments(0)ShellScript

2010年04月17日

シェルスクリプト(計算)

シェルスクリプトは数値を扱うのがあまり得意ではない
とはいっても扱う為のコマンドは用意されている
exprコマンドだ

使い方だが

expr 1 + 2

というコマンドを実行すれば3という答えが返ってくる
これを簡単なシェルスクリプトにしてみると

#!/usr/bin/sh
ans=`expr 1 + 2`
echo ”1 + 2 = ${ans}"


のようなものができあがる
いろいろな使い方があるので
紹介したいところだが
演算子だけ紹介するので
それぞれ試してみてほしい

算術演算子の一覧
  


Posted by タカさん at 20:47Comments(0)ShellScript

2010年04月06日

シェルスクリプト(変数の定義2)

変数の定義方法だが
この間やったものとは別方法を今回紹介する

1.readコマンドを利用した変数の定義
readコマンドは入力待ち状態にして
変数の中にデータを入れるのに使用する
たとえば次のようなシェルスクリプトがあるとする

#!/usr/bin/sh
echo "名前を入力して下さい=>¥c";read name
echo "あなたの名前は${name}さんですね"


これを実行すると
改行抑制の為のエスケープシーケンスもはいっているので
下の状態で入力待ちとなる

名前を入力して下さい=>

名前がhogehogeさんとして入力しEnterを押すと
次のような結果になる

名前を入力して下さい=>hogehoge
あなたの名前はhogehogeさんですね


となり
対話的な方法で変数nameにデータを格納することができ
とても便利だ

2.コマンドの実行結果を変数に格納する

下のようなシェルスクリプトがあるとする

#!/usr/bin/sh
testdata=`ls`
echo $testdata


以前紹介しechoコマンドの中で使用したが
変数に対してバッククォーテーションでコマンドをくくれば
コマンドの実行結果を変数の中に格納することができる

実行すればlsコマンドの結果が変数testdataに格納されているので
表示されることになる

これらの方法を組み合わせるだけでも
それなりのシェルスクリプトを作成することができる
ぜひ覚えよう  


Posted by タカさん at 20:53Comments(0)ShellScript

2010年04月04日

シェルスクリプト(変数内容の表示)

前回に少しふれたが
変数に格納した内容を表示するのに
「echo」コマンドを使用した
それについてもう少し詳しく説明したいと思う

echoコマンドを使用しての代表的な書式だが
1.echo 文字列
2.echo $変数名
3.echo "`コマンド`"


3に関してバッククォーテーションはコマンドの出力に置き換えることができる

echo “私は`whoami`です”

という記述であれば

私はuserです

というようにバッククォーテーションの中の内容がコマンド内容に置き換わる
この中でも変数の内容を出力するのに利用するのは
上記書式の項目のうち2というふうになる

shで使用する場合はエスケープシーケンスが用意されていて
改行を抑制したいりすることができ
bashの場合はオプションで同様の制御をすることができる
shを例にして改行の抑制を説明すると

echo "わたしの名前はhogehogeです¥c”
read stop


という記述であれば出力された時に

わたしの名前はhogehogeです

と表示された後に改行されずに出力された文字の最後尾で
入力待ちの状態となる
シェルスクリプトで入力を促す場合などによく使用される記述だ
他にもいろいろと用意されているが
一覧として紹介するので使ってみてほしい

代表的なエスケープシーケンス
  


Posted by タカさん at 21:12Comments(0)ShellScript

2010年04月01日

シェルスクリプト(変数の定義)

シェルスクリプトで変数を定義するのは
そんなに難しい方法ではない
書式は以下の通り

変数名=値

例:count=30


ただし注意があり 「=」の前後に空白は入れない
値の中に空白やメタキャラを含める場合は引 用符「“」で囲む

例:name=“nanashino gonbe”

これだけだ
内容を表示したい場合は「echo」コマンドなどで表示する

echo $name

のように定義した変数を参照する場合は
変数名の前に「$」をつける
変数を解除する場合は

unset name

のように記述する
ほかにも変数の中に値をいれる方法はあるが
それは進めながら紹介していくことにする  


Posted by タカさん at 07:02Comments(0)ShellScript

2010年03月30日

シェルスクリプト(変数の種類)

シェルスクリプト内で使用する変数には
シェル変数と環境変数の2種類がある
定義や参照方法は同じだが性質には違いがある。

シェル変数
変数を定義したシェル内のみ有効で
子プロセスには引き継がれない(引き継ぐ設定も可能)

環境変数
あらかじめシェルの環境を整えたり
コマンドを実行する為に必要な情報が定義されている
値を変更して定義しなおすことも可能である
環境変数は子プロセスに引き継がれる変数である。

変数名
一般にシェル変数名には小文字を使用し
環境変数名には大文字を使用する慣例があり
これによりどちらの変数であるか知ることができる

まあ・・・
これらは普段コマンドを利用したり
Linux自体の環境を設定する時にも
関係してくることなので
知ってると知らないとでは大違いだ
PATHを通すときですらこれらのことが関係してくる

(`・ω・´){覚えておこうね)  


Posted by タカさん at 20:48Comments(0)ShellScript

2010年03月28日

シェルスクリプト(作成要領)

シェルの作成はそんなに難しいことはない
Viエディタ等のエディタを使用して
ファイルにコマンドを書き込むのが作成方法となる

1行目には動作させるシェルを指定するのが基本で
指定すべきシェルを調べるには
「which」コマンドを使用する
たとえばshを実行シェルとして指定する場合だが
タカさんの環境では

which sh

とコマンドを実行すると

/usr/bin/sh

と返ってきた
これはshの場所を絶対パスで示したもので
その場合にはシェルの1行目に

#!/usr/bin/sh

のように、「#!」の後に記述する

コマンドを書き込んだだけでは動作しないので
ファイルに実行権を与えることで
シェルスクリプトとして動作するようになる
実行権を与えるには「chmod」 コマンドを使用する

ファイル名が「test.sh」であるならば

chmod u+x test.sh

といったように実行権を与える
実行権を与えたファイルは
ファイル名を指定することで実行することができる

たとえば

#!/usr/bin/sh

echo "test script"


と書き込まれたシェルスクリプトがある場合
実行結果は

test script

と出力されるはずだ
基本的な作成要領はこれだけで
あとは条件分岐などの制御文を組み合わせることで
いろいろな動作をさせることができるようになる

(`・ω・´){便利ですなあ)  


Posted by タカさん at 21:02Comments(0)ShellScript

2010年03月27日

シェルスクリプトの得意不得意

まあ・・・ここは簡単に流しておこう

得意なこと(メリット等
1.既存のコマンドを組み合わせて作れる
2.コンパイル不要
3.環境設定できる
4.テキスト行を処理する作業に向いている
5.CRONに登録し複雑な作業を自動化

不得意(デメリット等)
1.複雑な計算には不向き
2.文字ごとの処理は実行が遅い
3.シェルの種類によって記述が異なる

などがあり
特に記述に関しては
BourneShell系とCShell系にわかれる
タカさんはCShellもやるんだけど
とりあえずBourneShell系メインで進めていく  


Posted by タカさん at 17:47Comments(0)ShellScript

2010年03月27日

シェルスクリプトとは?

まずシェルスクリプトとはどんなものかというと・・・
簡単にいえばコマンドをファイルに書き込んだものである
シェルスクリプトのファイル名をコマンド名のように入力することで
キーボードからコマンドを1つずつ入力する替わりに
シェルスクリプト内のコマンドを順に実行させることができる

ファイルにはただコマンドを書き込むだけでなく
入出力の切り換えやパイプなどのメタキャラを使用したり
条件分岐や繰り返し処理を行うための制御文を使用することもできる
これによりUNIXが標準で提供しているコマンドを組み合わせるだけで
より複雑な処理を新しいコマンドのように動作させることが可能だ

(`・ω・´){覚えるとかなりイイよ)  


Posted by タカさん at 17:39Comments(0)ShellScript

2010年03月26日

このカテゴリーについて

シェルスクリプトの基本的なことを
とりあえず「Bourne Shell(ボーンシェル)」について残していくっす

(`・ω・´){練習問題も少し掲載するぞ)

LinuxやUnixやMac使いで
シェルスクリプトができない人は
がんばって覚えてみるといいかもね
カスタマイズの幅が広がりますよっと
  


Posted by タカさん at 21:11Comments(0)ShellScript