.bashrcに書いておくと微妙に役に立つ関数集

## n階層上位のdirectoryに移動する
```
function cdn(){
    if [ $# -eq 1 ]; then
        local temppath=`pwd`
        for i in `seq $1`; do temppath=$temppath'/..'; done
	cd $temppath
    else
        cd ../
    fi
    return 0
}
```
例えば5階層上位のdirectoryに移動したいときなどにいちいちcd ../../../../../とか打つのは面倒くさいが、この関数を使えば
```cdn 5```
と打つだけで良い。

## あるファイルが出現するまで待つ
```
function waitfor(){
    local slsec=10
    if [ $# -eq 2 ]; then
        slsec=$2
    fi
    if [ $# -gt 0 ]; then
        if [ ! -e $1 ]; then
            while [ ! -e $1 ]
            do
                sleep $slsec
            done
            sleep $slsec
        fi
    else
        echo "waitfor: argument is invalid." >&2
    fi
    return 0
}
```
```waitfor XXX.txt```
と実行すると10秒ごとにXXX.txtというファイルが存在するかどうかを確認する。
```waitfor XXX.txt 5```
と実行すると5秒ごとにXXX.txtというファイルが存在するかどうかを確認する。

あるファイルが出現したらYYYというコマンドを実行したいというときには
```waitfor XXX.txt && YYY```
と書くだけでそれが実現できるので便利。

## 現在のpathを保存する、過去に保存したpathに移動する
現在いるdirectoryを保存する関数

```
function savedir(){
    local file_path=[[[[[/path/to/yours]]]]]/.lastsaved.txt
    local file=(`cat "${file_path}"`)
    local num=`expr ${#file[@]} - 2`
    pwd > ${file_path}
    for i in `seq 0 ${num}`; do
        echo ${file[i]} >> ${file_path}
    done
    return 0
}
```
以前savedirで保存したdirectoryへ移動する関数

```
function godir(){
    local file_path=[[[[[/path/to/yours]]]]]/.lastsaved.txt
    local file=(`cat "${file_path}"`)
    if [ $# -eq 1 ]; then
        if [ $1 -gt `expr ${#file[@]} - 1` ]; then
            echo "moving:the input is greater than the saving num" 1>&2
        else
            cd ${file[$1]}
        fi
    else
        cd ${file[0]}
    fi
    return 0
}
```

上記それぞれで/path/to/yoursを適宜各自の好きなpathに書き換える必要あり、また[[[[[/path/to/yours]]]]]/.lastsaved.txtは事前に作成しておいて数行適当な文を書いておくこと。
　
```savedir```
で現在のdirectoryを保存できる。
```godir```
と入力すると直近に保存したdirectoryに移動する。
```godir 2```
と入力すると2回前に保存したdirectoryに移動する。

## n番目に新しく編集したファイル名を返す
```
function prevmod(){
    if [ $# -eq 1 ]; then
        ls -t | head -n $1 | tail -n 1
    else
        ls -t | head -n 1
    fi
    return 0
}
```

```prevmod 2```
と入力するとそのdirectory内で2番目に新しく編集したファイル名が返ってくる。
引数を省くと最後に編集したファイル名が返ってくる。
例えばshell scriptファイルを編集した後に
```./`prevmod````
と入力するとそのshell scriptファイルが実行されるため、directory内にファイルが多くなってきたときなどに重宝する。

## 頻繁に訪れるディレクトリへの移動をalias化する
### ディレクトリをaliasとして登録
[[[[[/path/to/yours]]]]]を各自の好きなpathに置き換える必要あり

```
function addalias(){
    if [ $# -eq 0 ]; then
        echo "addalias: argument is invalid." 1>&2
        return
    fi
    local wheretosave=`pwd`
    if [ $# -eq 2 ]; then
        wheretosave=$2
    fi
    alias $1='cd '$wheretosave
    local file_path=[[[[[/path/to/yours]]]]]/.newalias.txt
    local file=(`cat "${file_path}"`)
    local num=`expr ${#file[@]} - 1`
    echo $1 > ${file_path}
    echo `pwd` >> ${file_path}
    for i in `seq 0 ${num}`; do
        echo ${file[i]} >> ${file_path}
    done
}
```
`addalias hoge`を実行すると`hoge`と実行することで今いるディレクトリへ移動できるようになる(要するに`alias hoge='cd [今いるディレクトリ]`が実行される)
`addalias hoge /path/to/huga`を実行すると/path/to/hugaに`hoge`で移動できるようになる

### aliasに登録したディレクトリを削除
同様に[[[[[/path/to/yours]]]]]を各自の好きなpathに置き換える必要あり

```
function rmalias(){
    if [ $# -ne 0 ]; then
        echo "rmalias: argument is invalid." 1>&2
        return
    fi

    # load aliases and count num
    local file_path=[[[[[/path/to/yours]]]]]/.newalias.txt
    local file=(`cat "${file_path}"`)
    local num=`expr ${#file[@]} - 1`
    num=`expr ${num} / 2`

    # ask an alias to be removed
    local cur_i0=0
    local cur_i1=0
    local cur_i2=1
    for i in `seq 0 ${num}`; do
        echo "${cur_i0}: ${file[cur_i1]}='cd ${file[cur_i2]}'"
        cur_i0=$(( cur_i0 + 1 ))
        cur_i1=$(( cur_i1 + 2 ))
        cur_i2=$(( cur_i2 + 2 ))
    done
    local aliasnum
    read -p "select target: " aliasnum

    # dump aliases to a file
    cur_i0=0
    cur_i1=0
    cur_i2=1
    local cur_flg=true
    for i in `seq 0 ${num}`; do
        if [ $cur_i0 -ne $aliasnum ]; then
            if $cur_flg; then
                echo ${file[$cur_i1]} > ${file_path}
                cur_flg=false
            else
                echo ${file[$cur_i1]} >> ${file_path}
            fi
            echo ${file[$cur_i2]} >> ${file_path}
        else
            unalias ${file[$cur_i1]}
        fi
        cur_i0=$(( cur_i0 + 1 ))
        cur_i1=$(( cur_i1 + 2 ))
        cur_i2=$(( cur_i2 + 2 ))
    done
}
```
`rmalias`を実行すると以下のように既に登録されているaliasが表示される

```
0: hoge='cd /path/to/hoge'
1: huga='cd /path/to/huga'
2: asdf='cd /path/to/asdf'
select target:
```
この時に例えば1を入力してエンターを押すとhugaがaliasから削除されるといった仕様

なお、ログインするたびに以前保存したaliasを再び読み込むようにするには以下の文面をbashrcに書いておく必要がある
こちらも同様に[[[[[/path/to/yours]]]]]を各自の好きなpathに置き換える必要あり

```
file_path=[[[[[/path/to/yours]]]]]/.newalias.txt
file=(`cat "${file_path}"`)
num=`expr ${#file[@]} - 1`
num=`expr ${num} / 2`
cur_i1=0
cur_i2=1
for i in `seq 0 ${num}`; do
    alias ${file[cur_i1]}='cd '${file[cur_i2]}
    cur_i1=$(( cur_i1 + 2 ))
    cur_i2=$(( cur_i2 + 2 ))
done
```

## `screen -r`を強化する

```
function sr(){
    if [ $# -eq 0 ]; then
        local screen_result=(`screen -ls`)
        local var_num=${#screen_result[@]}
        if [ $var_num -le 15 ]; then
            screen -r
        else
            local cur_num=4
            local cur_ind=0
            while [ $(( cur_num + 5 )) -lt $var_num ]
            do
                echo "${cur_ind}: ${screen_result[$cur_num]} ${screen_result[$cur_num+1]} ${screen_result[$cur_num+2]} ${screen_result[$cur_num+3]} ${screen_result[$cur_num+4]}"
                cur_num=$(( cur_num + 5 ))
                cur_ind=$(( cur_ind + 1 ))
            done
            local screennum
            read -p "select target: " screennum
            if [ $screennum -lt 0 -o $screennum -ge $cur_ind ]; then
                echo "stest: input is invalid." >&2
            else
                cur_num=`expr 4 + 5 \* $screennum`
                screen -r ${screen_result[cur_num]}
            fi
        fi
    else
        screen -r $@
    fi
}
```

screenを使っている人向けのコマンド。
今立てているscreenが2つ以上の場合、`screen -r`を一覧の情報が表示されるだけであり、入るためにはもう一度そのコマンドをscreenの指定付きで実行する必要があるため面倒くさい。
screenが複数存在する場合に上記の関数`sr`を実行すると以下のような画面になる。

```
0: 10558.pts-22.tai (06/26/2016 06:49:01 PM) (Detached)
1: 10550.pts-22.tai (06/26/2016 06:48:57 PM) (Detached)
2: 37033.pts-22.tai (06/24/2016 09:11:41 PM) (Detached)
select target:
```
この時に例えば1を入力してエンターを押すと10550.pts-22.taiのscreenに入れて楽。