### 以日期為檔名命名
```bash
#!/bin/bash
# 獲取當前日期
current_date=$(date +%Y-%m-%d)
# 檔名
filename="file_${current_date}.txt"
# 使用檔名進行相應操作
echo "This is a sample file" > "$filename"
date +%Y-%m-%d # 2023-07-07
date +%Y%m%d # 20230707
```
### 函式
```bash
greet() {
local name=$1
echo "Hello, $name!"
}
greet "Alice" # 傳遞參數 "Alice" 給函式 greet
greet "Bob" # 傳遞參數 "Bob" 給函式 greet
```
帶有預設值的參數
```bash
#!/bin/bash
# 定義一個函式,帶有一個帶有預設值的參數
greet() {
name="${1:-Guest}" # 如果沒有提供參數,使用 "Guest" 作為預設值
echo "Hello, $name!"
}
# 呼叫函式,不提供參數
greet
# 呼叫函式,提供參數
greet "Alice"
```
### If
在bash中,if判斷式通常使用以下語法:
```
if [ 條件 ]; then
指令1
else
指令2
fi
```
其中,條件是一個表達式,可以是比較運算符、邏輯運算符或字串判斷,例如:
- 比較運算符:-eq (等於)、-ne (不等於)、-lt (小於)、-gt (大於)、-le (小於等於)、-ge (大於等於)
- 邏輯運算符:-a (且)、-o (或)、! (非)
- 字串判斷:= (等於)、!= (不等於)、-n (非空字串)
以下是一個簡單的if判斷式範例:
```
if [ $1 -eq 1 ]; then
echo "數字為1"
else
echo "數字不是1"
fi
```
在這個例子中,如果輸入的第一個參數等於1,則輸出"數字為1",否則輸出"數字不是1"。
```bash
# 定義一個字串變數
name="John"
# 如果您確定正在使用 sh 而不是 Bash,請改用單個等號 (=) 進行字串比較。
# 使用 if-else 進行字串判斷
if [ "$name" == "John" ]; then
echo "歡迎,John!"
else
echo "您不是 John。"
fi
```
### for
當使用 Bash 時,for 迴圈可用於重複執行特定的指令,以下是一個基本的範例:
```bash
#!/bin/bash
# 使用 for 迴圈列印出 1 到 5 的數字
for i in 1 2 3 4 5
do
echo $i
done
```
在這個範例中,for 迴圈會將變數 `i` 設定為每一個指定的值(1, 2, 3, 4, 5),並依序執行迴圈內部的指令 `echo $i`,將 `i` 的值印出來。
你也可以使用特定的範圍來設定 `for` 迴圈。以下是一個以數字範圍來設定迴圈的範例:
```bash
#!/bin/bash
# 使用 for 迴圈列印出 1 到 5 的數字
for i in {1..5}
do
echo $i
done
```
這個範例使用 `{1..5}` 來表示數字範圍從 1 到 5,for 迴圈會依序執行指定的指令。
### Input
```bash
# 提示使用者輸入
echo "請輸入您的名字:"
# 讀取使用者輸入並將其存入變數中
read name
# 使用讀取到的值進行後續處理
echo "您輸入的名字是:$name"
# 使用 Esc 作為結束字元
read -d $'\e' input
```
```bash
#!/bin/bash
# 使用 read 命令接收輸入,如果使用者直接按下 Enter 鍵,則使用預設值 "John"
read -p "Enter your name (default is John): " -r name
name=${name:-John}
# 顯示輸入值
echo "Your name is: $name"
```
### 連續輸入
以下是一個擁有連續請使用者輸入功能的bash腳本:
```bash
#!/bin/bash
inputs=()
while true; do
read -p "請輸入內容 (按下Esc退出): " input
# 檢查使用者是否按下Esc鍵
if [[ $input == $'\e' ]]; then
break
fi
inputs+=("$input")
done
echo "輸入的內容為:"
for item in "${inputs[@]}"; do
echo "$item"
done
```
可以保存上面的程式碼到一個檔案(例如 `input_script.sh`),然後在終端中執行以下命令:
```bash
bash input_script.sh
```
使用者將可以連續輸入內容,直到按下Esc鍵。所有輸入的內容將被存入串列並顯示在終端中。
### Here Document
```bash
#!/bin/bash
# 產生另一個 shell script
# 創建或覆蓋新的腳本文件 new_script.sh
cat << EOF > new_script.sh
#!/bin/bash
echo "This is the new script!"
EOF
# 給予可執行權限
chmod +x new_script.sh
echo "New script file 'new_script.sh' generated!"
```
### 資料夾或檔案
```bash
# 目前位置的所有檔案
for file in *; do
# 如果是資料夾
if [ -d "$file" ]; then
echo "$file is Folder"
fi
# 如果是檔案
if [ -f "$file" ]; then
echo "$file is File"
fi
done
```
### 檔名空白處理
```bash
filename=$(printf '%q' "$file")
```
### 僅檔名(不要副檔名)
```bash
filename_no_extension="${filename%.*}"
```
### eval
在bash shell中,`eval` 是一個用於執行字串中包含的命令的指令。它會將字串視為一個命令並執行它。`eval` 指令通常用於將變數或其他字串中的命令執行起來。
例如,假設有一個變數包含一個命令:
```
command="ls -l"
```
要執行這個命令,你可以使用 `eval` 指令:
```
eval $command
```
這將會顯示目前目錄下的所有檔案和資料夾的詳細資訊。
要注意的是,使用 `eval` 指令時,必須非常謹慎,特別是當命令是來自不受信任的來源時,因為它可能會造成安全漏洞或意外的結果。
```bash
#!/bin/bash
# 定義一個函式,接受命令字符串作為參數並執行它
run_command() {
command_to_run="$1"
echo "Running command: $command_to_run"
eval "$command_to_run"
}
# 使用 run_command 函式來執行不同的命令
run_command "ls -l"
run_command "echo Hello, World!"
```
### Debug
在 bash 腳本中,使用 `set -x` 可以啟用 debug 模式,會讓腳本的每一行在執行時都會被顯示出來。這樣可以幫助你追蹤程式執行的過程,找出問題所在。
要在腳本中啟用 debug 模式,只需要在腳本的一開始加入以下行:
```bash
set -x
```
接著執行腳本時,你會看到每一行指令被顯示出來,方便你檢查程式的執行過程。
```bash
$ bash myscript.sh
+ echo 'Hello, world!'
Hello, world!
+ echo 'This is a debug message'
This is a debug message
```
當你完成 debug 後,可以使用 `set +x` 來關閉 debug 模式:
```bash
set +x
```
這樣就可以關閉 debug 模式,腳本會恢復到正常執行狀態。
### 正規劃的判斷式(=~)使用說明及範例
在bash中,可以使用`=~`運算符來執行正規劃的判斷式。`=~`運算符可以用來比較一個字符串是否與一個正規劃模式匹配。如果匹配成功,則返回0,否則返回1。
以下是一個使用`=~`運算符的範例:
```bash
#!/bin/bash
input="Hello World"
pattern="o W"
if [[ $input =~ $pattern ]]; then
echo "Matched!"
else
echo "Not matched!"
fi
```
在這個例子中,我們將`$input`變量設置為"Hello World",將`$pattern`設置為"o W"。然後我們使用`=~`運算符來判斷`$input`是否匹配`$pattern`。因為"Hello World"中包含"o W",所以這個判斷式將返回0並輸出"Matched!"。
你也可以使用正規劃表達式作為`$pattern`,例如:
```bash
#!/bin/bash
email="test@example.com"
pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
if [[ $email =~ $pattern ]]; then
echo "Valid email address!"
else
echo "Invalid email address!"
fi
```
在這個例子中,我們使用一個正規劃表達式來驗證電子郵件地址的格式。如果`$email`是一個有效的電子郵件地址,則這個判斷式將返回0並輸出"Valid email address!"。
### While
`while` 是一個迴圈結構,能夠不斷重複執行特定的指令,直到滿足某個條件為止。
以下是一個簡單的 `while` 迴圈的範例:
```bash
#!/bin/bash
count=1
while [ $count -le 5 ]
do
echo "Count is: $count"
((count++))
done
```
在這個範例中,我們使用 `while [ $count -le 5 ]` 來設定迴圈的條件,即當 `count` 變數小於或等於 5 時,迴圈會不斷執行。在迴圈內部我們使用 `echo` 來輸出 `count` 的值,然後執行 `((count++))` 來將 `count` 變數加一。
當 `count` 變數等於 6 時,條件不再滿足,迴圈就會終止。
### While true
```bash
#!/bin/bash
count=1
while true
do
echo "Count: $count"
count=$((count+1))
if [ $count -eq 6 ]
then
break
fi
done
```
這個腳本會不斷地印出 count 變數的值,直到 count 等於 6 時才會停止執行並結束迴圈。當 count 變數達到 6 時,便會觸發 if 條件式並執行 break 來跳出迴圈。
### While 檔案讀取
在Bash腳本中,您可以使用while迴圈來讀取檔案的內容。以下是一個示例腳本,演示如何使用while迴圈從檔案中讀取每一行數據:
```bash
#!/bin/bash
# 請更換成您要讀取的檔案路徑
file="sample.txt"
# 使用while迴圈讀取檔案內容
while IFS= read -r line
do
echo "$line"
done < "$file"
```
在這個示例中,我們將檔案路徑指定給變數file,然後使用while迴圈和read命令來一行一行地讀取檔案中的內容並進行輸出。注意,我們使用<運算符將檔案作為迴圈的輸入。
您可以將這個示例腳本保存為一個.sh檔,然後在終端中運行它,來讀取檔案的內容並進行處理。
### 參數
在bash中,以下是一些特殊變數的含義和用法:
1. `$0`:代表目前執行的腳本名稱。
2. `$@`:代表所有參數的列表。
3. `$1`、`$2`、`$3`...:代表分別是第一個、第二個、第三個參數的值。
4. `$#`:代表參數的個數。
下面是一個示例腳本,假設腳本名稱為example.sh,有三個參數:
```bash
#!/bin/bash
echo "腳本名稱:$0"
echo "所有參數:$@"
echo "第一個參數:$1"
echo "第二個參數:$2"
echo "第三個參數:$3"
echo "參數個數:$#"
```
執行腳本時,可以透過以下方式傳入參數:
```bash
./example.sh arg1 arg2 arg3
```
輸出結果將如下:
```
腳本名稱:example.sh
所有參數:arg1 arg2 arg3
第一個參數:arg1
第二個參數:arg2
第三個參數:arg3
參數個數:3
```
### 讀取檔案
你可以使用以下的 bash 腳本來迴圈列出檔案的每一行:
```bash
#!/bin/bash
file="example.txt"
while IFS= read -r line; do
echo "$line"
done < "$file"
```
在這個範例中,`example.txt` 是要處理的檔案名稱,`while IFS= read -r line; do` 是一個迴圈,使用 `read` 命令來讀取檔案的每一行,再將每一行的內容輸出至螢幕上。這樣就可以逐行輸出檔案的內容了。
IFS 是 Input Field Separator 的縮寫,可以用來設定用來切割讀取資料的分隔符號。在這個例子中,我們將 IFS 設定為空格,以便讀取包含空格的每一行。這樣可以確保讀取到完整的每一行,並避免遺失空格。
### 隨機字串
```bash
#!/bin/bash
randomString() {
# 宣告字串亂數池
pool="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
# 要生成的亂數字串長度
length=$1
# 初始化結果字串
result=""
# 使用迴圈從亂數池中隨機取出字元,直到達到指定長度
for (( i=0; i<length; i++ )); do
# 取得隨機索引值
index=$((RANDOM % ${#pool}))
# 取得隨機字元並加入結果字串
result="${result}${pool:index:1}"
done
# 輸出結果
echo $result
}
randomString 10 #ph0DQjVcM3
randomString 20 #09WdUYAZm5OxI5V0bZdQ
randomString 30 #4yDkmgxdB73Cu3hj6VGvns0GnYGlS1
```
### 數字格式化
```bash
formatNumber() {
num=$1
result=$(printf "%06d" $num) # 使用 printf 函式補零到6位數
echo $result
}
# 呼叫函式並輸出結果
result=$(formatNumber 123)
echo $result
```