1. 程式人生 > >文件替換(交互式)

文件替換(交互式)

shell

技術分享

  在增量發版博文裏,自動識別目標文件路徑是采用了標記目錄特征。當部署環境多變時,會多有不便。這個替換程序,在使用時需要手動輸入目標目錄。當需要進一步自動化時,可以與 fint 配合使用。


  程序發布時,需要借助一個環境變量(DONATELLO_HOME),以保證函數調用的正常。

  程序目錄結構

.
├── bin
│   ├── mTime    # 暫未啟用
│   └── screensize    # 獲取終端寬度、高度,一個C語言程序
├── lib
│   ├── displayHeader     # 設計用來打印程序頭部格式,未啟用
│   ├── doReplace    # 庫文件,提供替換文件的函數
│   ├── findObjectFile    # 在目標路徑中,尋找新文件的路徑,處理多個文件的交互選擇
│   ├── getscreensize     # 處理bin下C語言程序的返回結構
│   ├── printObject    # 把替換的對應關系輸出到終端
│   └── progressBar    # 打印一個進度條,暫緩程序執行
└── Replace    # 主程序

  主程序 Replace:

#!/bin/bash
# Replace-1.3
# The author: donatello
# 
chkdep() {
    [ -z $1 ] && echo "Directory ?"
    [ -z $1 ] && exit 4
    [ ! -d $1 ] && echo "Without directory, please again."
    [ ! -d $1 ] && exit 6
    [ -d $1 ] && baseDirectory=$1
}
chkdep $1
# Format the "baseDirectory".
declare -g baseDirectory="$(dirname $baseDirectory)"/"$(basename $baseDirectory)"
declare -g fileName=$(ls -1R .)
declare -g -a objectFileName
declare -g -i obj=1
declare -gr father="${DONATELLO_HOME}/bin"
echo $father

clear
# Call the functions.
#. displayHeader
. ${father}/lib/findObjectFile
. ${father}/lib/printObject
. ${father}/lib/doReplace

# Define count function.
# Count the number of array elements.
count_objectFileName() {
    local -i k=${#objectFileName[@]}
    [ 1 -ge $k ] && echo -e "\t\fCheck for new files" && return 33
    return 0
}
#
findFile
#count_objectFileName && [ 33 -eq $? ] && exit 33
count_objectFileName
[ 33 -eq $? ] && exit 33
printOjectFileDirName
replaceFile
echo -e ‘\nShell script ends.‘
# Shell script over.


  尋找目標文件 findObjectFile

#!/bin/bash
# The command that will replace the file if exists.
MV="$(which --skip-alias mv) -v"

# Check input by user when there are many file directory will be confirm.
confirmInfo() {
    #echo "k=$k"
    while true; do
        # Print files there are same name.
        if [ 1 -lt $k ]; then
            echo -e "file of the same name:\f<< $i >>"
            for((i=1; i<=k; i++)); do
            #    name=$(env basename ${file[$i]})
            #    echo -e "\tNo.$i ${name}\n"
                echo -e "\tNo.$i ${file[$i]}\n"
            done
        fi

        # Confirm file.
        while true; do
            read -p "Please confirm the path of the file that will be replace. No.-> " -N 1 confirm 1>/dev/null && echo ""
            if [ $confirm -ge 1 ] && [ $confirm -le $k ]; then
                break
            else
                echo "No‘s error."
            fi
        done

        # Reconfirm file.
        read -p "Do you confirm you choice ? (yY/nN)... " -N 1 reconfirm && echo ""
        if [ ‘y‘ = $reconfirm ]; then
            clear
            break
        elif [ ‘n‘ = $reconfirm ]; then
            echo "Please confirm again."
        else
            echo "Char‘s invalid."
        fi
    done
    #printf "Good luck, the file is %s.\n" "file[$confirm]"
    return $confirm
}

# Find the file that will be replaced.
findFile() {
    local -a file
    local -i k=1
    local -i confirm=0
    local -l reconfirm=n

    for i in $(echo $fileName); do # cycle: A file is looped once.
        [ ! -f $i ] && continue

        objectFileName=$(find $baseDirectory -name $i -print)
        for item in $(echo "${objectFileName}"); do
            #echo "item $k: $item"
            file[$k]=${item}
            let k=k+1
        done
        k=${#file[@]}
        #echo $i $k

        # There is no file with the same name, direct replacement.
        if [ 1 -eq $k ]; then
            objectFileName[$obj]=${file[$k]}
            let obj=obj+1
        fi
        # When the same file name exist, the user is required
        # to confirm the correct file path.

        # Call local function: confirmInfo
        if [ 1 -lt $k ]; then
            confirmInfo
            k=$?
            #echo "The file is ${file[${answer}]}"
            objectFileName[$obj]=${file[$k]}
            let obj=obj+1
        fi

    #    sleep 1
        # variable reset.
        k=1
        unset file
        # over
    done
}

echo "Will find files..."
# Over


  打印輸出替換對應關系 printObject

#!/bin/bash

BASENAME=$(which --skip-alias basename)

printOjectFileDirName() {
    clear
    #. displayHeader
    echo "Print object files..."
    local -i k=${#objectFileName[@]}
    #echo "length, k=$k"
    for((i=1; i<k; i++)); do
        echo "Will move $(${BASENAME} ${objectFileName[$i]}) --->> ${objectFileName[$i]}"
    done

    . ${father}/lib/progressBar
}
# Over

  打印對象後,調用了進度條效果 progressBar

#!/bin/bash
#
declare -i cycle=1
declare -i length=15
declare -i k=0
#echo -n ‘-------------------------------------------------------‘

printBar(){
    for((i=0; i<length; i++)); do
        echo -n ‘-‘
    done

    printf "\r"
    for((i=0; i<cycle*length; i++)); do
            echo -n ‘-‘ && sleep 0.05
            echo -e -n ‘\b\‘ && sleep 0.05
            echo -e -n ‘\b-‘ && sleep 0.05
            echo -e -n ‘\b/‘ && sleep 0.05
            echo -e -n ‘\b*‘ && sleep 0.3
            echo -e -n ‘\b-‘

            let k=k+1
            if [ $k -eq $length ]
            then
                    k=0
                    printf "\r"
            fi
    done
}
printBar


  替換文件 doReplace:

#!/bin/bash
MV="$(which --skip-alias mv) -v"
BASENAME=$(which --skip-alias basename)

replaceFile() {
    clear
    echo "Replace object files..."
    local -i k=${#objectFileName[@]}
    for((i=1; i<k; i++)); do
        $MV $(${BASENAME} ${objectFileName[$i]}) ${objectFileName[$i]}
    done
}
# do it
# Over


  

  



本文出自 “開發型運維” 博客,謝絕轉載!

文件替換(交互式)