Shell腳本中字符串處理的實(shí)用技巧分享
前言
在 Linux 系統(tǒng)管理和自動(dòng)化運(yùn)維的世界中,Shell 腳本是不可或缺的工具。而字符串處理,則是 Shell 編程中最常用、最核心的功能之一。無(wú)論是日志分析、配置文件修改、用戶輸入校驗(yàn),還是系統(tǒng)狀態(tài)監(jiān)控,都離不開(kāi)對(duì)字符串的靈活操作。
本文將深入探討 Shell 腳本中各種實(shí)用的字符串處理技巧,從基礎(chǔ)語(yǔ)法到高級(jí)實(shí)戰(zhàn),結(jié)合 Java 代碼對(duì)比示例,幫助你全面掌握這一關(guān)鍵技能。無(wú)論你是剛?cè)腴T的新手,還是有一定經(jīng)驗(yàn)的開(kāi)發(fā)者,都能從中獲得實(shí)用的知識(shí)和靈感。
字符串基礎(chǔ):定義與賦值
在 Shell 中,字符串是最基本的數(shù)據(jù)類型。你可以使用單引號(hào)、雙引號(hào)或不加引號(hào)來(lái)定義字符串:
#!/bin/bash str1='Hello World' # 單引號(hào):內(nèi)容原樣輸出 str2="Hello $USER" # 雙引號(hào):支持變量擴(kuò)展 str3=Hello\ World # 不加引號(hào):需轉(zhuǎn)義空格 str4="Today is $(date)" # 支持命令替換 echo "$str1" echo "$str2" echo "$str3" echo "$str4"
注意:?jiǎn)我?hào)內(nèi)的所有內(nèi)容都會(huì)被當(dāng)作字面量,不會(huì)進(jìn)行變量替換或命令執(zhí)行。
Java 對(duì)比示例:
public class StringBasics {
public static void main(String[] args) {
String str1 = "Hello World"; // 相當(dāng)于 Shell 單引號(hào)
String user = System.getProperty("user.name");
String str2 = "Hello " + user; // 相當(dāng)于 Shell 雙引號(hào)變量拼接
String str3 = "Hello World"; // Java 中空格無(wú)需轉(zhuǎn)義
String str4 = "Today is " + java.time.LocalDate.now(); // 命令替換對(duì)應(yīng)
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
}
}字符串長(zhǎng)度計(jì)算
獲取字符串長(zhǎng)度是常見(jiàn)的需求,在 Shell 中有多種方式:
#!/bin/bash
text="Hello, Shell Programming!"
# 方法1:使用 ${#variable}
len1=${#text}
echo "方法1 - 長(zhǎng)度: $len1"
# 方法2:使用 expr length
len2=$(expr length "$text")
echo "方法2 - 長(zhǎng)度: $len2"
# 方法3:使用 wc -m(注意會(huì)包含換行符)
len3=$(echo -n "$text" | wc -m)
echo "方法3 - 長(zhǎng)度: $len3"
# 方法4:使用 awk
len4=$(echo "$text" | awk '{print length}')
echo "方法4 - 長(zhǎng)度: $len4"
實(shí)戰(zhàn)應(yīng)用:密碼強(qiáng)度檢查
#!/bin/bash
check_password_strength() {
local password="$1"
local length=${#password}
if [ $length -lt 8 ]; then
echo "? 密碼太短,至少需要8個(gè)字符"
return 1
elif [ $length -lt 12 ]; then
echo "?? 密碼長(zhǎng)度合格,但建議使用12位以上"
return 0
else
echo "? 密碼長(zhǎng)度優(yōu)秀!"
return 0
fi
}
# 測(cè)試
check_password_strength "abc123"
check_password_strength "mySecurePassword123"
Java 對(duì)比示例:
public class StringLength {
public static void checkPasswordStrength(String password) {
int length = password.length();
if (length < 8) {
System.out.println("? 密碼太短,至少需要8個(gè)字符");
} else if (length < 12) {
System.out.println("?? 密碼長(zhǎng)度合格,但建議使用12位以上");
} else {
System.out.println("? 密碼長(zhǎng)度優(yōu)秀!");
}
}
public static void main(String[] args) {
checkPasswordStrength("abc123");
checkPasswordStrength("mySecurePassword123");
// 其他長(zhǎng)度計(jì)算方法
String text = "Hello, Java Programming!";
System.out.println("長(zhǎng)度: " + text.length());
System.out.println("字節(jié)數(shù): " + text.getBytes().length);
}
}字符串截取與切片
Shell 提供了強(qiáng)大的字符串截取功能,讓你可以輕松提取子字符串。
基礎(chǔ)截取語(yǔ)法
#!/bin/bash
str="Hello World Shell Scripting"
# 從位置0開(kāi)始,取5個(gè)字符
substr1=${str:0:5}
echo "前5個(gè)字符: $substr1" # 輸出: Hello
# 從位置6開(kāi)始到結(jié)尾
substr2=${str:6}
echo "從第7個(gè)字符開(kāi)始: $substr2" # 輸出: World Shell Scripting
# 從倒數(shù)第8個(gè)字符開(kāi)始,取6個(gè)字符
substr3=${str: -8:6}
echo "倒數(shù)第8個(gè)開(kāi)始取6個(gè): $substr3" # 輸出: Script
# 僅指定起始位置(到結(jié)尾)
substr4=${str:12}
echo "從第13個(gè)字符開(kāi)始: $substr4" # 輸出: Shell Scripting
實(shí)戰(zhàn)應(yīng)用:文件路徑處理
#!/bin/bash
process_filepath() {
local filepath="$1"
echo "原始路徑: $filepath"
# 獲取文件名(最后一個(gè)/之后的內(nèi)容)
filename=${filepath##*/}
echo "文件名: $filename"
# 獲取目錄路徑(最后一個(gè)/之前的內(nèi)容)
dirpath=${filepath%/*}
echo "目錄路徑: $dirpath"
# 獲取文件擴(kuò)展名
extension=${filename##*.}
echo "擴(kuò)展名: $extension"
# 獲取不含擴(kuò)展名的文件名
basename=${filename%.*}
echo "基礎(chǔ)文件名: $basename"
}
# 測(cè)試
process_filepath "/home/user/documents/report.pdf"
process_filepath "/var/log/system.log"
使用 cut 命令截取
#!/bin/bash data="John,Doe,30,Engineer,New York" # 按逗號(hào)分隔,取第1字段 first_name=$(echo "$data" | cut -d',' -f1) echo "名字: $first_name" # 取第1-2字段 name=$(echo "$data" | cut -d',' -f1-2) echo "姓名: $name" # 取第3和第5字段 age_city=$(echo "$data" | cut -d',' -f3,5) echo "年齡和城市: $age_city" # 按字符位置截取 char_slice=$(echo "$data" | cut -c1-10) echo "前10個(gè)字符: $char_slice"
Java 對(duì)比示例:
public class StringSubstring {
public static void processFilepath(String filepath) {
System.out.println("原始路徑: " + filepath);
// 獲取文件名
int lastSlash = filepath.lastIndexOf('/');
String filename = lastSlash == -1 ? filepath : filepath.substring(lastSlash + 1);
System.out.println("文件名: " + filename);
// 獲取目錄路徑
String dirpath = lastSlash == -1 ? "" : filepath.substring(0, lastSlash);
System.out.println("目錄路徑: " + dirpath);
// 獲取文件擴(kuò)展名
int lastDot = filename.lastIndexOf('.');
String extension = lastDot == -1 ? "" : filename.substring(lastDot + 1);
System.out.println("擴(kuò)展名: " + extension);
// 獲取不含擴(kuò)展名的文件名
String basename = lastDot == -1 ? filename : filename.substring(0, lastDot);
System.out.println("基礎(chǔ)文件名: " + basename);
}
public static void main(String[] args) {
String str = "Hello World Shell Scripting";
// 基礎(chǔ)截取
System.out.println("前5個(gè)字符: " + str.substring(0, 5));
System.out.println("從第7個(gè)字符開(kāi)始: " + str.substring(6));
// 處理CSV數(shù)據(jù)
String data = "John,Doe,30,Engineer,New York";
String[] fields = data.split(",");
System.out.println("名字: " + fields[0]);
System.out.println("姓名: " + fields[0] + "," + fields[1]);
System.out.println("年齡和城市: " + fields[2] + "," + fields[4]);
System.out.println("前10個(gè)字符: " + data.substring(0, Math.min(10, data.length())));
// 處理文件路徑
processFilepath("/home/user/documents/report.pdf");
}
}字符串查找與定位
在 Shell 中查找字符串的位置和判斷是否存在是常見(jiàn)需求。
使用 expr index 查找字符位置
#!/bin/bash
text="Hello World"
# 查找第一個(gè) 'o' 的位置(從1開(kāi)始計(jì)數(shù))
pos=$(expr index "$text" "o")
echo "第一個(gè) 'o' 的位置: $pos"
# 查找字符集中的任意字符
pos2=$(expr index "$text" "aeiou")
echo "第一個(gè)元音字母的位置: $pos2"
# 判斷字符是否存在
if [ $pos -gt 0 ]; then
echo "? 找到了 'o'"
else
echo "? 未找到 'o'"
fi
使用 grep 判斷字符串存在
#!/bin/bash
check_string_contains() {
local haystack="$1"
local needle="$2"
if echo "$haystack" | grep -q "$needle"; then
echo "? '$needle' 存在于 '$haystack'"
return 0
else
echo "? '$needle' 不存在于 '$haystack'"
return 1
fi
}
# 測(cè)試
check_string_contains "Hello World" "World"
check_string_contains "Hello World" "Python"
check_string_contains "The quick brown fox" "quick"
查找所有匹配位置
#!/bin/bash
find_all_positions() {
local text="$1"
local search="$2"
local pos=0
local found=0
echo "在 '$text' 中查找 '$search':"
while true; do
# 從當(dāng)前位置開(kāi)始查找
temp=${text:$pos}
index=$(expr index "$temp" "$search")
if [ $index -eq 0 ]; then
break
fi
actual_pos=$((pos + index - 1))
echo " 位置 $actual_pos"
pos=$((actual_pos + 1))
found=1
done
if [ $found -eq 0 ]; then
echo " 未找到匹配項(xiàng)"
fi
}
# 測(cè)試
find_all_positions "banana" "a"
find_all_positions "programming" "m"
Java 對(duì)比示例:
import java.util.ArrayList;
import java.util.List;
public class StringSearch {
public static boolean containsString(String haystack, String needle) {
boolean found = haystack.contains(needle);
if (found) {
System.out.println("? '" + needle + "' 存在于 '" + haystack + "'");
} else {
System.out.println("? '" + needle + "' 不存在于 '" + haystack + "'");
}
return found;
}
public static List<Integer> findAllPositions(String text, String search) {
List<Integer> positions = new ArrayList<>();
int index = 0;
System.out.println("在 '" + text + "' 中查找 '" + search + "':");
while ((index = text.indexOf(search, index)) != -1) {
positions.add(index);
System.out.println(" 位置 " + index);
index += 1; // 移動(dòng)到下一個(gè)位置
}
if (positions.isEmpty()) {
System.out.println(" 未找到匹配項(xiàng)");
}
return positions;
}
public static void main(String[] args) {
String text = "Hello World";
// 查找字符位置
int pos = text.indexOf('o');
System.out.println("第一個(gè) 'o' 的位置: " + (pos + 1)); // Java從0開(kāi)始,Shell從1開(kāi)始
// 查找元音字母
String vowels = "aeiou";
int firstVowelPos = -1;
for (int i = 0; i < text.length(); i++) {
if (vowels.indexOf(text.charAt(i)) != -1) {
firstVowelPos = i;
break;
}
}
System.out.println("第一個(gè)元音字母的位置: " + (firstVowelPos + 1));
// 測(cè)試包含判斷
containsString("Hello World", "World");
containsString("Hello World", "Python");
// 查找所有位置
findAllPositions("banana", "a");
findAllPositions("programming", "m");
}
}字符串替換與修改
Shell 提供了多種字符串替換的方法,從簡(jiǎn)單的全局替換到復(fù)雜的正則表達(dá)式替換。
基礎(chǔ)替換語(yǔ)法
#!/bin/bash
text="Hello World, Hello Shell, Hello Linux"
# 替換第一個(gè)匹配項(xiàng)
result1=${text/Hello/Hi}
echo "替換第一個(gè): $result1"
# 替換所有匹配項(xiàng)
result2=${text//Hello/Hi}
echo "替換所有: $result2"
# 替換開(kāi)頭匹配項(xiàng)
result3=${text/#Hello/Hi}
echo "替換開(kāi)頭: $result3"
# 替換結(jié)尾匹配項(xiàng)
result4=${text/%Linux/Unix}
echo "替換結(jié)尾: $result4"
# 刪除匹配項(xiàng)(替換為空)
result5=${text//Hello/}
echo "刪除所有Hello: $result5"
使用 sed 進(jìn)行高級(jí)替換
#!/bin/bash text="User: John, Age: 30, City: New York" # 基礎(chǔ)替換 result1=$(echo "$text" | sed 's/John/Jane/g') echo "替換名字: $result1" # 使用正則表達(dá)式 result2=$(echo "$text" | sed 's/Age: [0-9][0-9]/Age: 35/g') echo "更新年齡: $result2" # 多次替換 result3=$(echo "$text" | sed -e 's/John/Jane/g' -e 's/30/35/g' -e 's/New York/Boston/g') echo "多重替換: $result3" # 條件替換 result4=$(echo "$text" | sed '/John/s/Age: 30/Age: 35/') echo "條件替換: $result4"
實(shí)戰(zhàn)應(yīng)用:批量重命名文件
#!/bin/bash
rename_files() {
local old_pattern="$1"
local new_pattern="$2"
local directory="${3:-.}"
echo "在目錄 '$directory' 中將 '$old_pattern' 替換為 '$new_pattern'"
for file in "$directory"/*; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [[ "$filename" == *"$old_pattern"* ]]; then
new_filename=${filename//$old_pattern/$new_pattern}
mv "$file" "$directory/$new_filename"
echo "? 重命名: $filename → $new_filename"
fi
fi
done
}
# 使用示例(注釋掉實(shí)際執(zhí)行,僅顯示邏輯)
# rename_files "draft_" "final_" "./documents"
# rename_files ".txt" ".md" "./notes"
Java 對(duì)比示例:
public class StringReplace {
public static void main(String[] args) {
String text = "Hello World, Hello Shell, Hello Linux";
// 替換第一個(gè)匹配項(xiàng)
String result1 = text.replaceFirst("Hello", "Hi");
System.out.println("替換第一個(gè): " + result1);
// 替換所有匹配項(xiàng)
String result2 = text.replaceAll("Hello", "Hi");
System.out.println("替換所有: " + result2);
// 替換開(kāi)頭匹配項(xiàng)
String result3 = text.startsWith("Hello") ? "Hi" + text.substring(5) : text;
System.out.println("替換開(kāi)頭: " + result3);
// 替換結(jié)尾匹配項(xiàng)
String result4 = text.endsWith("Linux") ?
text.substring(0, text.length() - 5) + "Unix" : text;
System.out.println("替換結(jié)尾: " + result4);
// 刪除匹配項(xiàng)
String result5 = text.replaceAll("Hello", "");
System.out.println("刪除所有Hello: " + result5);
// 使用正則表達(dá)式
String userData = "User: John, Age: 30, City: New York";
String result6 = userData.replaceAll("John", "Jane");
System.out.println("替換名字: " + result6);
String result7 = userData.replaceAll("Age: \\d+", "Age: 35");
System.out.println("更新年齡: " + result7);
// 多重替換
String result8 = userData
.replace("John", "Jane")
.replace("30", "35")
.replace("New York", "Boston");
System.out.println("多重替換: " + result8);
}
}正則表達(dá)式匹配
Shell 中的正則表達(dá)式功能強(qiáng)大,可以幫助你進(jìn)行復(fù)雜的字符串模式匹配。
基礎(chǔ)正則匹配
#!/bin/bash
validate_email() {
local email="$1"
local email_regex='^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if [[ "$email" =~ $email_regex ]]; then
echo "? 有效的郵箱地址: $email"
return 0
else
echo "? 無(wú)效的郵箱地址: $email"
return 1
fi
}
validate_phone() {
local phone="$1"
local phone_regex='^(\+?1[-.\s]?)?\(?([0-9]{3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})$'
if [[ "$phone" =~ $phone_regex ]]; then
echo "? 有效的電話號(hào)碼: $phone"
# 提取區(qū)號(hào)
echo "區(qū)號(hào): ${BASH_REMATCH[2]}"
return 0
else
echo "? 無(wú)效的電話號(hào)碼: $phone"
return 1
fi
}
# 測(cè)試
validate_email "user@example.com"
validate_email "invalid.email"
validate_phone "123-456-7890"
validate_phone "(555) 123-4567"
validate_phone "+1 555 123 4567"
使用 grep 進(jìn)行正則匹配
#!/bin/bash
# 創(chuàng)建測(cè)試數(shù)據(jù)
cat > test_data.txt << EOF
john.doe@example.com
invalid.email
jane.smith@company.org
user123@gmail.com
not_an_email
admin@site.co.uk
EOF
echo "=== 郵箱驗(yàn)證結(jié)果 ==="
while IFS= read -r line; do
if echo "$line" | grep -qE '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'; then
echo "? $line"
else
echo "? $line"
fi
done < test_data.txt
# 提取特定格式的數(shù)據(jù)
echo -e "\n=== 提取.com郵箱 ==="
grep -E '@[^.]*\.com$' test_data.txt
# 統(tǒng)計(jì)匹配數(shù)量
count=$(grep -cE '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' test_data.txt)
echo -e "\n有效郵箱總數(shù): $count"
# 清理測(cè)試文件
rm test_data.txt
復(fù)雜模式匹配示例
#!/bin/bash
analyze_log_entry() {
local log_entry="$1"
# 匹配日志格式: [日期 時(shí)間] [級(jí)別] 消息
local log_pattern='^\[([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})\] \[([A-Z]+)\] (.*)$'
if [[ "$log_entry" =~ $log_pattern ]]; then
echo "? 有效的日志條目"
echo "日期: ${BASH_REMATCH[1]}"
echo "時(shí)間: ${BASH_REMATCH[2]}"
echo "級(jí)別: ${BASH_REMATCH[3]}"
echo "消息: ${BASH_REMATCH[4]}"
return 0
else
echo "? 無(wú)效的日志格式: $log_entry"
return 1
fi
}
# 測(cè)試
analyze_log_entry "[2024-01-15 14:30:25] [ERROR] Database connection failed"
analyze_log_entry "[2024-01-15 14:31:10] [INFO] User login successful"
analyze_log_entry "Invalid log format"
Java 對(duì)比示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatching {
public static boolean validateEmail(String email) {
String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
Pattern pattern = Pattern.compile(emailRegex);
Matcher matcher = pattern.matcher(email);
if (matcher.matches()) {
System.out.println("? 有效的郵箱地址: " + email);
return true;
} else {
System.out.println("? 無(wú)效的郵箱地址: " + email);
return false;
}
}
public static boolean validatePhone(String phone) {
String phoneRegex = "^(\\+?1[-.\\s]?)?\\(?([0-9]{3})\\)?[-.\\s]?([0-9]{3})[-.\\s]?([0-9]{4})$";
Pattern pattern = Pattern.compile(phoneRegex);
Matcher matcher = pattern.matcher(phone);
if (matcher.matches()) {
System.out.println("? 有效的電話號(hào)碼: " + phone);
// 提取區(qū)號(hào)
System.out.println("區(qū)號(hào): " + matcher.group(2));
return true;
} else {
System.out.println("? 無(wú)效的電話號(hào)碼: " + phone);
return false;
}
}
public static void analyzeLogEntry(String logEntry) {
// 匹配日志格式: [日期 時(shí)間] [級(jí)別] 消息
String logPattern = "^\\[([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})\\] \\[([A-Z]+)\\] (.*)$";
Pattern pattern = Pattern.compile(logPattern);
Matcher matcher = pattern.matcher(logEntry);
if (matcher.matches()) {
System.out.println("? 有效的日志條目");
System.out.println("日期: " + matcher.group(1));
System.out.println("時(shí)間: " + matcher.group(2));
System.out.println("級(jí)別: " + matcher.group(3));
System.out.println("消息: " + matcher.group(4));
} else {
System.out.println("? 無(wú)效的日志格式: " + logEntry);
}
}
public static void main(String[] args) {
// 測(cè)試郵箱驗(yàn)證
validateEmail("user@example.com");
validateEmail("invalid.email");
// 測(cè)試電話驗(yàn)證
validatePhone("123-456-7890");
validatePhone("(555) 123-4567");
validatePhone("+1 555 123 4567");
// 測(cè)試日志分析
analyzeLogEntry("[2024-01-15 14:30:25] [ERROR] Database connection failed");
analyzeLogEntry("[2024-01-15 14:31:10] [INFO] User login successful");
analyzeLogEntry("Invalid log format");
// 使用正則表達(dá)式提取數(shù)據(jù)
String testData = "john.doe@example.com\ninvalid.email\njane.smith@company.org";
String[] lines = testData.split("\n");
System.out.println("\n=== 郵箱驗(yàn)證結(jié)果 ===");
int validCount = 0;
for (String line : lines) {
if (validateEmail(line)) {
validCount++;
}
}
System.out.println("\n有效郵箱總數(shù): " + validCount);
}
}字符串分割與數(shù)組處理
將字符串分割成數(shù)組是處理結(jié)構(gòu)化數(shù)據(jù)的重要技能。
使用 IFS 分割字符串
#!/bin/bash
split_with_ifs() {
local string="$1"
local delimiter="$2"
echo "原始字符串: $string"
echo "分隔符: '$delimiter'"
# 保存原來(lái)的IFS
OLD_IFS=$IFS
IFS=$delimiter
# 分割字符串
read -ra parts <<< "$string"
# 恢復(fù)IFS
IFS=$OLD_IFS
echo "分割結(jié)果:"
for i in "${!parts[@]}"; do
echo " [$i]: '${parts[i]}'"
done
echo "總共有 ${#parts[@]} 個(gè)部分"
}
# 測(cè)試不同分隔符
split_with_ifs "apple,banana,cherry,date" ","
echo ""
split_with_ifs "red|green|blue|yellow" "|"
echo ""
split_with_ifs "one two three four" " "
使用 cut 和 awk 分割
#!/bin/bash
process_csv_data() {
local csv_line="$1"
echo "CSV數(shù)據(jù): $csv_line"
# 使用cut分割
name=$(echo "$csv_line" | cut -d',' -f1)
age=$(echo "$csv_line" | cut -d',' -f2)
city=$(echo "$csv_line" | cut -d',' -f3)
echo "使用cut分割:"
echo " 姓名: $name"
echo " 年齡: $age"
echo " 城市: $city"
# 使用awk分割
echo "使用awk分割:"
echo "$csv_line" | awk -F',' '{
printf " 姓名: %s\n", $1
printf " 年齡: %s\n", $2
printf " 城市: %s\n", $3
printf " 總字段數(shù): %d\n", NF
}'
}
# 測(cè)試
process_csv_data "張三,25,北京"
echo ""
process_csv_data "李四,30,上海"
復(fù)雜分割場(chǎng)景
#!/bin/bash
parse_config_line() {
local config_line="$1"
echo "配置行: $config_line"
# 處理 key=value 格式
if [[ "$config_line" == *"="* ]]; then
# 使用IFS分割
OLD_IFS=$IFS
IFS='='
read -ra parts <<< "$config_line"
IFS=$OLD_IFS
if [ ${#parts[@]} -eq 2 ]; then
key=$(echo "${parts[0]}" | xargs) # 去除前后空格
value=$(echo "${parts[1]}" | xargs) # 去除前后空格
echo "鍵: '$key'"
echo "值: '$value'"
# 進(jìn)一步處理值(如果包含逗號(hào)分隔的列表)
if [[ "$value" == *","* ]]; then
OLD_IFS=$IFS
IFS=','
read -ra list_items <<< "$value"
IFS=$OLD_IFS
echo "列表項(xiàng):"
for item in "${list_items[@]}"; do
trimmed_item=$(echo "$item" | xargs)
echo " - $trimmed_item"
done
fi
fi
fi
}
# 測(cè)試
parse_config_line "database.host=localhost"
echo ""
parse_config_line "allowed.origins=http://example.com, https://api.example.com, http://localhost:3000"
echo ""
parse_config_line "max.connections=100"
數(shù)組操作技巧
#!/bin/bash
array_operations() {
local string="$1"
local delimiter="$2"
echo "=== 數(shù)組操作演示 ==="
echo "源字符串: $string"
# 創(chuàng)建數(shù)組
OLD_IFS=$IFS
IFS=$delimiter
read -ra arr <<< "$string"
IFS=$OLD_IFS
echo "數(shù)組內(nèi)容: ${arr[*]}"
echo "數(shù)組長(zhǎng)度: ${#arr[@]}"
# 遍歷數(shù)組
echo "遍歷數(shù)組:"
for i in "${!arr[@]}"; do
echo " 索引 $i: ${arr[i]}"
done
# 添加元素
arr+=("new_element")
echo "添加元素后: ${arr[*]}"
# 刪除元素
unset 'arr[1]' # 刪除索引1的元素
echo "刪除索引1后: ${arr[*]}"
# 連接數(shù)組元素
joined=$(IFS=$delimiter; echo "${arr[*]}")
echo "重新連接: $joined"
# 排序數(shù)組
sorted=($(for i in "${arr[@]}"; do echo "$i"; done | sort))
echo "排序后: ${sorted[*]}"
}
# 測(cè)試
array_operations "zebra,apple,banana,cherry" ","
Java 對(duì)比示例:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StringSplitting {
public static void splitWithString(String string, String delimiter) {
System.out.println("原始字符串: " + string);
System.out.println("分隔符: '" + delimiter + "'");
// 分割字符串
String[] parts = string.split(delimiter);
System.out.println("分割結(jié)果:");
for (int i = 0; i < parts.length; i++) {
System.out.println(" [" + i + "]: '" + parts[i] + "'");
}
System.out.println("總共有 " + parts.length + " 個(gè)部分");
}
public static void processCsvData(String csvLine) {
System.out.println("CSV數(shù)據(jù): " + csvLine);
// 分割CSV
String[] fields = csvLine.split(",");
System.out.println("分割結(jié)果:");
System.out.println(" 姓名: " + fields[0]);
System.out.println(" 年齡: " + fields[1]);
System.out.println(" 城市: " + fields[2]);
System.out.println(" 總字段數(shù): " + fields.length);
}
public static void parseConfigLine(String configLine) {
System.out.println("配置行: " + configLine);
// 處理 key=value 格式
if (configLine.contains("=")) {
String[] parts = configLine.split("=", 2); // 最多分割成2部分
String key = parts[0].trim();
String value = parts[1].trim();
System.out.println("鍵: '" + key + "'");
System.out.println("值: '" + value + "'");
// 進(jìn)一步處理值(如果包含逗號(hào)分隔的列表)
if (value.contains(",")) {
String[] listItems = value.split(",");
System.out.println("列表項(xiàng):");
for (String item : listItems) {
System.out.println(" - " + item.trim());
}
}
}
}
public static void arrayOperations(String string, String delimiter) {
System.out.println("=== 數(shù)組操作演示 ===");
System.out.println("源字符串: " + string);
// 創(chuàng)建數(shù)組
String[] arr = string.split(delimiter);
System.out.println("數(shù)組內(nèi)容: " + Arrays.toString(arr));
System.out.println("數(shù)組長(zhǎng)度: " + arr.length);
// 遍歷數(shù)組
System.out.println("遍歷數(shù)組:");
for (int i = 0; i < arr.length; i++) {
System.out.println(" 索引 " + i + ": " + arr[i]);
}
// 添加元素(需要?jiǎng)?chuàng)建新數(shù)組)
String[] newArr = Arrays.copyOf(arr, arr.length + 1);
newArr[arr.length] = "new_element";
System.out.println("添加元素后: " + Arrays.toString(newArr));
// 刪除元素(需要?jiǎng)?chuàng)建新數(shù)組)
List<String> list = Arrays.asList(newArr).stream()
.filter((item, index) -> index != 1)
.collect(Collectors.toList());
System.out.println("刪除索引1后: " + list);
// 連接數(shù)組元素
String joined = String.join(delimiter, newArr);
System.out.println("重新連接: " + joined);
// 排序數(shù)組
String[] sorted = newArr.clone();
Arrays.sort(sorted);
System.out.println("排序后: " + Arrays.toString(sorted));
}
public static void main(String[] args) {
// 測(cè)試不同分隔符
splitWithString("apple,banana,cherry,date", ",");
System.out.println();
splitWithString("red|green|blue|yellow", "\\|");
System.out.println();
splitWithString("one two three four", " ");
// 測(cè)試CSV處理
System.out.println();
processCsvData("張三,25,北京");
// 測(cè)試配置解析
System.out.println();
parseConfigLine("database.host=localhost");
System.out.println();
parseConfigLine("allowed.origins=http://example.com, https://api.example.com, http://localhost:3000");
// 測(cè)試數(shù)組操作
System.out.println();
arrayOperations("zebra,apple,banana,cherry", ",");
}
}字符串大小寫轉(zhuǎn)換
在文本處理中,經(jīng)常需要轉(zhuǎn)換字符串的大小寫格式。
使用 tr 命令轉(zhuǎn)換
#!/bin/bash
convert_case() {
local text="$1"
echo "原始文本: $text"
# 轉(zhuǎn)換為大寫
upper=$(echo "$text" | tr '[:lower:]' '[:upper:]')
echo "大寫: $upper"
# 轉(zhuǎn)換為小寫
lower=$(echo "$text" | tr '[:upper:]' '[:lower:]')
echo "小寫: $lower"
# 首字母大寫
first_upper=$(echo "$text" | sed 's/.*/\L&/; s/[a-z]/\U&/')
echo "首字母大寫: $first_upper"
# 每個(gè)單詞首字母大寫
title_case=$(echo "$text" | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2));}1')
echo "標(biāo)題格式: $title_case"
}
# 測(cè)試
convert_case "hello world shell scripting"
echo ""
convert_case "PYTHON JAVA JAVASCRIPT"
使用 Bash 內(nèi)建功能(4.0+版本)
#!/bin/bash
# 檢查Bash版本
echo "Bash版本: $BASH_VERSION"
if [[ ${BASH_VERSION%%.*} -ge 4 ]]; then
echo "使用Bash 4.0+內(nèi)建大小寫轉(zhuǎn)換功能"
text="hello WORLD Shell Scripting"
echo "原始文本: $text"
# 轉(zhuǎn)換為大寫
echo "大寫: ${text^^}"
# 轉(zhuǎn)換為小寫
echo "小寫: ${text,,}"
# 首字母大寫
echo "首字母大寫: ${text^}"
# 首字母小寫
echo "首字母小寫: ${text,}"
# 對(duì)特定字符進(jìn)行大小寫轉(zhuǎn)換
echo "轉(zhuǎn)換特定字符(l→L): ${text^^l}"
echo "轉(zhuǎn)換特定字符(S→s): ${text,,S}"
else
echo "Bash版本低于4.0,使用tr命令替代"
text="hello WORLD Shell Scripting"
echo "大寫: $(echo "$text" | tr '[:lower:]' '[:upper:]')"
echo "小寫: $(echo "$text" | tr '[:upper:]' '[:lower:]')"
fi
實(shí)戰(zhàn)應(yīng)用:標(biāo)準(zhǔn)化文件名
#!/bin/bash
standardize_filename() {
local filename="$1"
local format="$2" # snake, kebab, camel, pascal
echo "原始文件名: $filename"
echo "目標(biāo)格式: $format"
# 移除擴(kuò)展名
name="${filename%.*}"
extension="${filename##*.}"
has_extension=$([ "$filename" != "$name" ] && echo "true" || echo "false")
case $format in
"snake")
# 轉(zhuǎn)換為snake_case
result=$(echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9]/_/g' | sed 's/__*/_/g' | sed 's/^_//;s/_$//')
;;
"kebab")
# 轉(zhuǎn)換為kebab-case
result=$(echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
;;
"camel")
# 轉(zhuǎn)換為camelCase
temp=$(echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9]/ /g')
result=$(echo "$temp" | awk '{
for(i=1; i<=NF; i++) {
if(i==1) {
printf "%s", $i
} else {
printf "%s%s", toupper(substr($i,1,1)), substr($i,2)
}
}
}')
;;
"pascal")
# 轉(zhuǎn)換為PascalCase
temp=$(echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9]/ /g')
result=$(echo "$temp" | awk '{
for(i=1; i<=NF; i++) {
printf "%s%s", toupper(substr($i,1,1)), substr($i,2)
}
}')
;;
*)
echo "未知格式: $format"
return 1
;;
esac
# 重新添加擴(kuò)展名
if [ "$has_extension" = "true" ]; then
result="$result.$extension"
fi
echo "標(biāo)準(zhǔn)化后: $result"
return 0
}
# 測(cè)試不同格式
standardize_filename "My Document FINAL v2.pdf" "snake"
echo ""
standardize_filename "user_profile_settings.json" "kebab"
echo ""
standardize_filename "HELLO-WORLD-TEST.TXT" "camel"
echo ""
standardize_filename "data backup 2024.csv" "pascal"
Java 對(duì)比示例:
import java.util.Arrays;
import java.util.regex.Pattern;
public class CaseConversion {
public static void convertCase(String text) {
System.out.println("原始文本: " + text);
// 轉(zhuǎn)換為大寫
String upper = text.toUpperCase();
System.out.println("大寫: " + upper);
// 轉(zhuǎn)換為小寫
String lower = text.toLowerCase();
System.out.println("小寫: " + lower);
// 首字母大寫
String firstUpper = text.isEmpty() ? text :
text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase();
System.out.println("首字母大寫: " + firstUpper);
// 每個(gè)單詞首字母大寫
String titleCase = Arrays.stream(text.split("\\s+"))
.map(word -> word.isEmpty() ? word :
word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase())
.collect(Collectors.joining(" "));
System.out.println("標(biāo)題格式: " + titleCase);
}
public static String standardizeFilename(String filename, String format) {
System.out.println("原始文件名: " + filename);
System.out.println("目標(biāo)格式: " + format);
// 分離文件名和擴(kuò)展名
int lastDot = filename.lastIndexOf('.');
String name = lastDot == -1 ? filename : filename.substring(0, lastDot);
String extension = lastDot == -1 ? "" : filename.substring(lastDot);
boolean hasExtension = lastDot != -1;
String result;
switch (format.toLowerCase()) {
case "snake":
// 轉(zhuǎn)換為snake_case
result = name.toLowerCase()
.replaceAll("[^a-zA-Z0-9]", "_")
.replaceAll("_+", "_")
.replaceAll("^_|_$", "");
break;
case "kebab":
// 轉(zhuǎn)換為kebab-case
result = name.toLowerCase()
.replaceAll("[^a-zA-Z0-9]", "-")
.replaceAll("-+", "-")
.replaceAll("^-|-$", "");
break;
case "camel":
// 轉(zhuǎn)換為camelCase
String[] words = name.toLowerCase().split("[^a-zA-Z0-9]+");
StringBuilder camelBuilder = new StringBuilder();
for (int i = 0; i < words.length; i++) {
if (i == 0) {
camelBuilder.append(words[i]);
} else if (!words[i].isEmpty()) {
camelBuilder.append(
words[i].substring(0, 1).toUpperCase() +
words[i].substring(1)
);
}
}
result = camelBuilder.toString();
break;
case "pascal":
// 轉(zhuǎn)換為PascalCase
String[] pascalWords = name.toLowerCase().split("[^a-zA-Z0-9]+");
StringBuilder pascalBuilder = new StringBuilder();
for (String word : pascalWords) {
if (!word.isEmpty()) {
pascalBuilder.append(
word.substring(0, 1).toUpperCase() +
word.substring(1)
);
}
}
result = pascalBuilder.toString();
break;
default:
System.out.println("未知格式: " + format);
return filename;
}
// 重新添加擴(kuò)展名
if (hasExtension) {
result = result + extension;
}
System.out.println("標(biāo)準(zhǔn)化后: " + result);
return result;
}
public static void main(String[] args) {
// 測(cè)試大小寫轉(zhuǎn)換
convertCase("hello world shell scripting");
System.out.println();
convertCase("PYTHON JAVA JAVASCRIPT");
// 測(cè)試文件名標(biāo)準(zhǔn)化
System.out.println();
standardizeFilename("My Document FINAL v2.pdf", "snake");
System.out.println();
standardizeFilename("user_profile_settings.json", "kebab");
System.out.println();
standardizeFilename("HELLO-WORLD-TEST.TXT", "camel");
System.out.println();
standardizeFilename("data backup 2024.csv", "pascal");
}
}字符串比較與條件判斷
字符串比較是 Shell 腳本中常用的條件判斷操作。
基礎(chǔ)字符串比較
#!/bin/bash
basic_string_comparison() {
local str1="$1"
local str2="$2"
echo "比較: '$str1' 和 '$str2'"
# 等于比較
if [ "$str1" = "$str2" ]; then
echo "? 字符串相等 (使用 =)"
else
echo "? 字符串不相等 (使用 =)"
fi
# 不等于比較
if [ "$str1" != "$str2" ]; then
echo "? 字符串不相等 (使用 !=)"
else
echo "? 字符串相等 (使用 !=)"
fi
# 使用雙括號(hào)(更現(xiàn)代的語(yǔ)法)
if [[ "$str1" == "$str2" ]]; then
echo "? 字符串相等 (使用 ==)"
else
echo "? 字符串不相等 (使用 ==)"
fi
# 長(zhǎng)度比較
if [ ${#str1} -eq ${#str2} ]; then
echo "? 長(zhǎng)度相等: ${#str1} = ${#str2}"
else
echo "? 長(zhǎng)度不相等: ${#str1} ≠ ${#str2}"
fi
# 字典序比較
if [[ "$str1" < "$str2" ]]; then
echo "? '$str1' 在字典序中小于 '$str2'"
elif [[ "$str1" > "$str2" ]]; then
echo "? '$str1' 在字典序中大于 '$str2'"
else
echo "? '$str1' 在字典序中等于 '$str2'"
fi
}
# 測(cè)試
basic_string_comparison "hello" "hello"
echo ""
basic_string_comparison "hello" "world"
echo ""
basic_string_comparison "apple" "banana"
模式匹配比較
#!/bin/bash
pattern_matching() {
local string="$1"
local pattern="$2"
echo "檢查: '$string' 是否匹配模式 '$pattern'"
# 使用通配符匹配
if [[ "$string" == $pattern ]]; then
echo "? 匹配成功"
else
echo "? 匹配失敗"
fi
# 常見(jiàn)模式示例
echo -e "\n=== 常見(jiàn)模式匹配示例 ==="
# 以特定字符開(kāi)頭
if [[ "$string" == h* ]]; then
echo "? 以 'h' 開(kāi)頭"
fi
# 以特定字符結(jié)尾
if [[ "$string" == *d ]]; then
echo "? 以 'd' 結(jié)尾"
fi
# 包含特定子串
if [[ "$string" == *ll* ]]; then
echo "? 包含 'll'"
fi
# 特定長(zhǎng)度
if [[ "$string" == ???? ]]; then
echo "? 長(zhǎng)度為4"
fi
# 字符集合
if [[ "$string" == [aeiou]* ]]; then
echo "? 以元音字母開(kāi)頭"
fi
}
# 測(cè)試
pattern_matching "hello" "h*"
echo ""
pattern_matching "world" "*d"
echo ""
pattern_matching "shell" "*ll*"
實(shí)戰(zhàn)應(yīng)用:文件類型檢測(cè)
#!/bin/bash
detect_file_type() {
local filename="$1"
echo "檢測(cè)文件: $filename"
# 獲取文件擴(kuò)展名
extension="${filename##*.}"
basename="${filename%.*}"
echo "文件名: $basename"
echo "擴(kuò)展名: $extension"
# 根據(jù)擴(kuò)展名判斷文件類型
case "$extension" in
"txt"|"md"|"log")
echo "?? 文本文件"
;;
"jpg"|"jpeg"|"png"|"gif"|"bmp")
echo "??? 圖像文件"
;;
"mp3"|"wav"|"ogg"|"flac")
echo "?? 音頻文件"
;;
"mp4"|"avi"|"mkv"|"mov")
echo "?? 視頻文件"
;;
"pdf")
echo "?? PDF文件"
;;
"zip"|"tar"|"gz"|"rar"|"7z")
echo "?? 壓縮文件"
;;
"sh"|"bash"|"zsh")
echo "?? Shell腳本"
;;
"py")
echo "?? Python腳本"
;;
"java")
echo "? Java源碼"
;;
"js"|"ts")
echo "?? JavaScript/TypeScript"
;;
"html"|"htm")
echo "?? HTML文件"
;;
"css")
echo "?? CSS樣式表"
;;
"json"|"xml"|"yaml"|"yml")
echo "?? 配置文件"
;;
*)
echo "? 未知文件類型"
;;
esac
# 檢查文件名特征
if [[ "$basename" == *"test"* || "$basename" == *"Test"* ]]; then
echo "?? 可能是測(cè)試文件"
fi
if [[ "$basename" == *"backup"* || "$basename" == *"Backup"* ]]; then
echo "?? 可能是備份文件"
fi
if [[ "$basename" == *"temp"* || "$basename" == *"Temp"* ]]; then
echo "??? 可能是臨時(shí)文件"
fi
}
# 測(cè)試
detect_file_type "document.txt"
echo ""
detect_file_type "photo.jpg"
echo ""
detect_file_type "script.sh"
echo ""
detect_file_type "test_data.json"
Java 對(duì)比示例:
public class StringComparison {
public static void basicStringComparison(String str1, String str2) {
System.out.println("比較: '" + str1 + "' 和 '" + str2 + "'");
// 等于比較
if (str1.equals(str2)) {
System.out.println("? 字符串相等 (使用 equals)");
} else {
System.out.println("? 字符串不相等 (使用 equals)");
}
// 不等于比較
if (!str1.equals(str2)) {
System.out.println("? 字符串不相等 (使用 !equals)");
} else {
System.out.println("? 字符串相等 (使用 !equals)");
}
// 忽略大小寫的比較
if (str1.equalsIgnoreCase(str2)) {
System.out.println("? 字符串相等 (忽略大小寫)");
}
// 長(zhǎng)度比較
if (str1.length() == str2.length()) {
System.out.println("? 長(zhǎng)度相等: " + str1.length() + " = " + str2.length());
} else {
System.out.println("? 長(zhǎng)度不相等: " + str1.length() + " ≠ " + str2.length());
}
// 字典序比較
int compareResult = str1.compareTo(str2);
if (compareResult < 0) {
System.out.println("? '" + str1 + "' 在字典序中小于 '" + str2 + "'");
} else if (compareResult > 0) {
System.out.println("? '" + str1 + "' 在字典序中大于 '" + str2 + "'");
} else {
System.out.println("? '" + str1 + "' 在字典序中等于 '" + str2 + "'");
}
}
public static void patternMatching(String string, String pattern) {
System.out.println("檢查: '" + string + "' 是否匹配模式 '" + pattern + "'");
// 使用正則表達(dá)式進(jìn)行模式匹配
boolean matches = string.matches(pattern);
if (matches) {
System.out.println("? 匹配成功");
} else {
System.out.println("? 匹配失敗");
}
System.out.println("\n=== 常見(jiàn)模式匹配示例 ===");
// 以特定字符開(kāi)頭
if (string.startsWith("h")) {
System.out.println("? 以 'h' 開(kāi)頭");
}
// 以特定字符結(jié)尾
if (string.endsWith("d")) {
System.out.println("? 以 'd' 結(jié)尾");
}
// 包含特定子串
if (string.contains("ll")) {
System.out.println("? 包含 'll'");
}
// 特定長(zhǎng)度
if (string.length() == 4) {
System.out.println("? 長(zhǎng)度為4");
}
// 使用正則表達(dá)式匹配元音字母開(kāi)頭
if (string.matches("[aeiouAEIOU].*")) {
System.out.println("? 以元音字母開(kāi)頭");
}
}
public static void detectFileType(String filename) {
System.out.println("檢測(cè)文件: " + filename);
// 獲取文件擴(kuò)展名
int lastDot = filename.lastIndexOf('.');
String basename = lastDot == -1 ? filename : filename.substring(0, lastDot);
String extension = lastDot == -1 ? "" : filename.substring(lastDot + 1);
System.out.println("文件名: " + basename);
System.out.println("擴(kuò)展名: " + extension);
// 根據(jù)擴(kuò)展名判斷文件類型
switch (extension.toLowerCase()) {
case "txt":
case "md":
case "log":
System.out.println("?? 文本文件");
break;
case "jpg":
case "jpeg":
case "png":
case "gif":
case "bmp":
System.out.println("??? 圖像文件");
break;
case "mp3":
case "wav":
case "ogg":
case "flac":
System.out.println("?? 音頻文件");
break;
case "mp4":
case "avi":
case "mkv":
case "mov":
System.out.println("?? 視頻文件");
break;
case "pdf":
System.out.println("?? PDF文件");
break;
case "zip":
case "tar":
case "gz":
case "rar":
case "7z":
System.out.println("?? 壓縮文件");
break;
case "sh":
case "bash":
case "zsh":
System.out.println("?? Shell腳本");
break;
case "py":
System.out.println("?? Python腳本");
break;
case "java":
System.out.println("? Java源碼");
break;
case "js":
case "ts":
System.out.println("?? JavaScript/TypeScript");
break;
case "html":
case "htm":
System.out.println("?? HTML文件");
break;
case "css":
System.out.println("?? CSS樣式表");
break;
case "json":
case "xml":
case "yaml":
case "yml":
System.out.println("?? 配置文件");
break;
default:
System.out.println("? 未知文件類型");
break;
}
// 檢查文件名特征
if (basename.toLowerCase().contains("test")) {
System.out.println("?? 可能是測(cè)試文件");
}
if (basename.toLowerCase().contains("backup")) {
System.out.println("?? 可能是備份文件");
}
if (basename.toLowerCase().contains("temp")) {
System.out.println("??? 可能是臨時(shí)文件");
}
}
public static void main(String[] args) {
// 測(cè)試基礎(chǔ)字符串比較
basicStringComparison("hello", "hello");
System.out.println();
basicStringComparison("hello", "world");
System.out.println();
basicStringComparison("apple", "banana");
// 測(cè)試模式匹配
System.out.println();
patternMatching("hello", "h.*"); // Java使用正則表達(dá)式
System.out.println();
patternMatching("world", ".*d");
System.out.println();
patternMatching("shell", ".*ll.*");
// 測(cè)試文件類型檢測(cè)
System.out.println();
detectFileType("document.txt");
System.out.println();
detectFileType("photo.jpg");
System.out.println();
detectFileType("script.sh");
System.out.println();
detectFileType("test_data.json");
}
}字符串格式化與對(duì)齊
良好的格式化可以讓輸出更加美觀和易讀。
使用 printf 格式化
#!/bin/bash
format_with_printf() {
echo "=== printf 格式化示例 ==="
# 基本字符串格式化
printf "姓名: %-15s 年齡: %3d\n" "張三" 25
printf "姓名: %-15s 年齡: %3d\n" "李四" 30
printf "姓名: %-15s 年齡: %3d\n" "王五" 28
echo ""
# 數(shù)字格式化
printf "整數(shù): %d\n" 123
printf "浮點(diǎn)數(shù): %.2f\n" 3.14159
printf "貨幣: $%.2f\n" 1234.567
printf "百分比: %.1f%%\n" 75.5
echo ""
# 對(duì)齊和填充
printf "左對(duì)齊: '%-10s'\n" "Hello"
printf "右對(duì)齊: '%10s'\n" "Hello"
printf "零填充: '%08d'\n" 123
printf "空格填充: '%8d'\n" 123
echo ""
# 表格格式化
printf "%-20s %-10s %-10s\n" "產(chǎn)品名稱" "價(jià)格" "庫(kù)存"
printf "%-20s %-10s %-10s\n" "------------------" "------" "------"
printf "%-20s $%-9.2f %-10d\n" "筆記本電腦" 899.99 15
printf "%-20s $%-9.2f %-10d\n" "鼠標(biāo)" 29.99 50
printf "%-20s $%-9.2f %-10d\n" "鍵盤" 79.99 25
}
format_with_printf
使用 column 命令創(chuàng)建表格
#!/bin/bash
create_table_with_column() {
echo "=== 使用 column 命令創(chuàng)建表格 ==="
# 創(chuàng)建制表符分隔的數(shù)據(jù)
cat > temp_data.txt << EOF
姓名 年齡 城市 職業(yè)
張三 25 北京 工程師
李四 30 上海 設(shè)計(jì)師
王五 28 廣州 產(chǎn)品經(jīng)理
趙六 35 深圳 架構(gòu)師
EOF
# 使用column命令格式化
echo "基本表格:"
column -t -s $'\t' temp_data.txt
echo ""
echo "帶分隔線的表格:"
{
head -n 1 temp_data.txt
echo "---- ---- ---- ----"
tail -n +2 temp_data.txt
} | column -t -s $'\t'
# 清理臨時(shí)文件
rm temp_data.txt
}
create_table_with_column
自定義對(duì)齊函數(shù)
#!/bin/bash
# 左對(duì)齊函數(shù)
left_align() {
local text="$1"
local width="$2"
local fill="${3:- }" # 默認(rèn)填充字符為空格
local text_length=${#text}
if [ $text_length -ge $width ]; then
echo "$text"
else
local padding_length=$((width - text_length))
local padding=$(printf "%${padding_length}s" | tr ' ' "$fill")
echo -n "$text"
echo "$padding"
fi
}
# 右對(duì)齊函數(shù)
right_align() {
local text="$1"
local width="$2"
local fill="${3:- }" # 默認(rèn)填充字符為空格
local text_length=${#text}
if [ $text_length -ge $width ]; then
echo "$text"
else
local padding_length=$((width - text_length))
local padding=$(printf "%${padding_length}s" | tr ' ' "$fill")
echo -n "$padding"
echo "$text"
fi
}
# 居中對(duì)齊函數(shù)
center_align() {
local text="$1"
local width="$2"
local fill="${3:- }" # 默認(rèn)填充字符為空格
local text_length=${#text}
if [ $text_length -ge $width ]; then
echo "$text"
else
local total_padding=$((width - text_length))
local left_padding=$((total_padding / 2))
local right_padding=$((total_padding - left_padding))
local left_pad=$(printf "%${left_padding}s" | tr ' ' "$fill")
local right_pad=$(printf "%${right_padding}s" | tr ' ' "$fill")
echo -n "$left_pad"
echo -n "$text"
echo "$right_pad"
fi
}
# 測(cè)試對(duì)齊函數(shù)
echo "=== 自定義對(duì)齊函數(shù)測(cè)試 ==="
echo "原始文本: 'Hello World'"
echo "左對(duì)齊 (寬度20): '$(left_align "Hello World" 20)'"
echo "右對(duì)齊 (寬度20): '$(right_align "Hello World" 20)'"
echo "居中對(duì)齊 (寬度20): '$(center_align "Hello World" 20)'"
echo "左對(duì)齊 (寬度20, 填充*): '$(left_align "Hello World" 20 "*")'"
echo "右對(duì)齊 (寬度20, 填充*): '$(right_align "Hello World" 20 "*")'"
echo "居中對(duì)齊 (寬度20, 填充*): '$(center_align "Hello World" 20 "*")'"
# 創(chuàng)建美觀的菜單
create_beautiful_menu() {
echo ""
echo "$(center_align "=== 系統(tǒng)管理菜單 ===" 40 "=")"
echo "$(left_align "1. 用戶管理" 30)$(right_align "按 1 選擇" 10)"
echo "$(left_align "2. 文件管理" 30)$(right_align "按 2 選擇" 10)"
echo "$(left_align "3. 網(wǎng)絡(luò)配置" 30)$(right_align "按 3 選擇" 10)"
echo "$(left_align "4. 系統(tǒng)監(jiān)控" 30)$(right_align "按 4 選擇" 10)"
echo "$(left_align "5. 退出系統(tǒng)" 30)$(right_align "按 5 選擇" 10)"
echo "$(center_align "" 40 "=")"
}
create_beautiful_menu
Java 對(duì)比示例:
public class StringFormatting {
public static void formatWithPrintf() {
System.out.println("=== printf 格式化示例 ===");
// 基本字符串格式化
System.out.printf("姓名: %-15s 年齡: %3d%n", "張三", 25);
System.out.printf("姓名: %-15s 年齡: %3d%n", "李四", 30);
System.out.printf("姓名: %-15s 年齡: %3d%n", "王五", 28);
System.out.println();
// 數(shù)字格式化
System.out.printf("整數(shù): %d%n", 123);
System.out.printf("浮點(diǎn)數(shù): %.2f%n", 3.14159);
System.out.printf("貨幣: $%.2f%n", 1234.567);
System.out.printf("百分比: %.1f%%%n", 75.5);
System.out.println();
// 對(duì)齊和填充
System.out.printf("左對(duì)齊: '%-10s'%n", "Hello");
System.out.printf("右對(duì)齊: '%10s'%n", "Hello");
System.out.printf("零填充: '%08d'%n", 123);
System.out.printf("空格填充: '%8d'%n", 123);
System.out.println();
// 表格格式化
System.out.printf("%-20s %-10s %-10s%n", "產(chǎn)品名稱", "價(jià)格", "庫(kù)存");
System.out.printf("%-20s %-10s %-10s%n", "------------------", "------", "------");
System.out.printf("%-20s $%-9.2f %-10d%n", "筆記本電腦", 899.99, 15);
System.out.printf("%-20s $%-9.2f %-10d%n", "鼠標(biāo)", 29.99, 50);
System.out.printf("%-20s $%-9.2f %-10d%n", "鍵盤", 79.99, 25);
}
// 左對(duì)齊函數(shù)
public static String leftAlign(String text, int width, char fill) {
if (text.length() >= width) {
return text;
}
int paddingLength = width - text.length();
StringBuilder padding = new StringBuilder();
for (int i = 0; i < paddingLength; i++) {
padding.append(fill);
}
return text + padding.toString();
}
// 右對(duì)齊函數(shù)
public static String rightAlign(String text, int width, char fill) {
if (text.length() >= width) {
return text;
}
int paddingLength = width - text.length();
StringBuilder padding = new StringBuilder();
for (int i = 0; i < paddingLength; i++) {
padding.append(fill);
}
return padding.toString() + text;
}
// 居中對(duì)齊函數(shù)
public static String centerAlign(String text, int width, char fill) {
if (text.length() >= width) {
return text;
}
int totalPadding = width - text.length();
int leftPadding = totalPadding / 2;
int rightPadding = totalPadding - leftPadding;
StringBuilder result = new StringBuilder();
for (int i = 0; i < leftPadding; i++) {
result.append(fill);
}
result.append(text);
for (int i = 0; i < rightPadding; i++) {
result.append(fill);
}
return result.toString();
}
public static void createBeautifulMenu() {
System.out.println();
System.out.println(centerAlign("=== 系統(tǒng)管理菜單 ===", 40, '='));
System.out.println(leftAlign("1. 用戶管理", 30, ' ') + rightAlign("按 1 選擇", 10, ' '));
System.out.println(leftAlign("2. 文件管理", 30, ' ') + rightAlign("按 2 選擇", 10, ' '));
System.out.println(leftAlign("3. 網(wǎng)絡(luò)配置", 30, ' ') + rightAlign("按 3 選擇", 10, ' '));
System.out.println(leftAlign("4. 系統(tǒng)監(jiān)控", 30, ' ') + rightAlign("按 4 選擇", 10, ' '));
System.out.println(leftAlign("5. 退出系統(tǒng)", 30, ' ') + rightAlign("按 5 選擇", 10, ' '));
System.out.println(centerAlign("", 40, '='));
}
public static void main(String[] args) {
// 測(cè)試printf格式化
formatWithPrintf();
// 測(cè)試對(duì)齊函數(shù)
System.out.println("\n=== 自定義對(duì)齊函數(shù)測(cè)試 ===");
System.out.println("原始文本: 'Hello World'");
System.out.println("左對(duì)齊 (寬度20): '" + leftAlign("Hello World", 20, ' ') + "'");
System.out.println("右對(duì)齊 (寬度20): '" + rightAlign("Hello World", 20, ' ') + "'");
System.out.println("居中對(duì)齊 (寬度20): '" + centerAlign("Hello World", 20, ' ') + "'");
System.out.println("左對(duì)齊 (寬度20, 填充*): '" + leftAlign("Hello World", 20, '*') + "'");
System.out.println("右對(duì)齊 (寬度20, 填充*): '" + rightAlign("Hello World", 20, '*') + "'");
System.out.println("居中對(duì)齊 (寬度20, 填充*): '" + centerAlign("Hello World", 20, '*') + "'");
// 創(chuàng)建美觀的菜單
createBeautifulMenu();
}
}高級(jí)字符串處理技巧
現(xiàn)在讓我們探索一些更高級(jí)的字符串處理技巧,這些技巧可以解決復(fù)雜的實(shí)際問(wèn)題。
多行字符串處理
#!/bin/bash
process_multiline_string() {
# 創(chuàng)建多行字符串
local multiline_text="第一行文本
第二行包含特殊字符 !@#$%^&*
第三行數(shù)字 123456
第四行混合內(nèi)容 abc123XYZ
第五行結(jié)束文本"
echo "=== 多行字符串處理 ==="
echo "原始文本:"
echo "$multiline_text"
echo ""
# 按行分割處理
echo "按行處理:"
line_number=1
while IFS= read -r line; do
echo "第${line_number}行: '$line'"
((line_number++))
done <<< "$multiline_text"
echo ""
# 統(tǒng)計(jì)行數(shù)
line_count=$(echo "$multiline_text" | wc -l)
echo "總行數(shù): $line_count"
# 提取特定行
second_line=$(echo "$multiline_text" | sed -n '2p')
echo "第二行: $second_line"
# 處理每行(去除空格、轉(zhuǎn)換大小寫等)
echo ""
echo "處理后的文本:"
echo "$multiline_text" | while IFS= read -r line; do
# 去除首尾空格
trimmed=$(echo "$line" | xargs)
# 轉(zhuǎn)換為大寫
upper=$(echo "$trimmed" | tr '[:lower:]' '[:upper:]')
echo "$upper"
done
}
process_multiline_string
字符串編碼轉(zhuǎn)換
#!/bin/bash
handle_encoding() {
echo "=== 字符串編碼處理 ==="
# 創(chuàng)建包含中文的測(cè)試文本
local chinese_text="你好,世界!Hello, World!"
echo "原始文本: $chinese_text"
# 轉(zhuǎn)換為UTF-8(通常默認(rèn)就是UTF-8)
utf8_text=$(echo "$chinese_text" | iconv -f UTF-8 -t UTF-8 2>/dev/null || echo "$chinese_text")
echo "UTF-8編碼: $utf8_text"
# 如果系統(tǒng)支持,可以嘗試其他編碼轉(zhuǎn)換
if command -v iconv >/dev/null 2>&1; then
echo "支持iconv命令,可以進(jìn)行編碼轉(zhuǎn)換"
# 顯示可用編碼
echo "部分可用編碼:"
iconv -l | head -5
# 嘗試GB2312編碼(如果支持)
if echo "$chinese_text" | iconv -f UTF-8 -t GB2312 >/dev/null 2>&1; then
gb2312_text=$(echo "$chinese_text" | iconv -f UTF-8 -t GB2312)
echo "GB2312編碼轉(zhuǎn)換成功"
else
echo "GB2312編碼轉(zhuǎn)換不支持"
fi
else
echo "系統(tǒng)不支持iconv命令"
fi
# URL編碼
url_encode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o
for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}"
}
# URL解碼
url_decode() {
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\\x}"
}
# 測(cè)試URL編碼
url_encoded=$(url_encode "$chinese_text")
echo "URL編碼: $url_encoded"
url_decoded=$(url_decode "$url_encoded")
echo "URL解碼: $url_decoded"
}
handle_encoding
字符串模板引擎
#!/bin/bash
# 簡(jiǎn)單的模板引擎實(shí)現(xiàn)
template_engine() {
local template="$1"
shift
local params=("$@")
echo "=== 模板引擎 ==="
echo "模板: $template"
echo "參數(shù): ${params[*]}"
echo ""
# 替換 {0}, {1}, {2}... 格式的占位符
result="$template"
for i in "${!params[@]}"; do
placeholder="{${i}}"
result=${result//${placeholder}/${params[i]}}
done
# 替換 {name} 格式的命名占位符
for param in "${params[@]}"; do
if [[ "$param" == *"="* ]]; then
name="${param%%=*}"
value="${param#*=}"
placeholder="{${name}}"
result=${result//${placeholder}/${value}}
fi
done
echo "結(jié)果: $result"
return 0
}
# 測(cè)試模板引擎
template_engine "Hello {0}, welcome to {1}!" "John" "Shell Scripting"
echo ""
template_engine "用戶 {name} 在 {time} 登錄系統(tǒng),IP地址: {ip}" \
"name=張三" "time=2024-01-15 14:30:25" "ip=192.168.1.100"
echo ""
template_engine "訂單號(hào): {order_id}, 商品: {product}, 數(shù)量: {quantity}, 總價(jià): ¥{price}" \
"order_id=ORD2024001" "product=筆記本電腦" "quantity=1" "price=8999.00"
字符串性能優(yōu)化技巧
#!/bin/bash
# 性能測(cè)試函數(shù)
performance_test() {
local iterations=10000
echo "=== 字符串操作性能測(cè)試 ($iterations 次迭代) ==="
# 測(cè)試字符串連接性能
echo "1. 字符串連接性能測(cè)試:"
# 方法1:使用 += 操作符
start_time=$(date +%s%N)
result1=""
for ((i=0; i<iterations; i++)); do
result1+="a"
done
end_time=$(date +%s%N)
time1=$((end_time - start_time))
echo " += 操作符: ${time1:0:-6}ms (長(zhǎng)度: ${#result1})"
# 方法2:使用數(shù)組然后join
start_time=$(date +%s%N)
declare -a arr2
for ((i=0; i<iterations; i++)); do
arr2+=("a")
done
result2=$(IFS=; echo "${arr2[*]}")
end_time=$(date +%s%N)
time2=$((end_time - start_time))
echo " 數(shù)組join: ${time2:0:-6}ms (長(zhǎng)度: ${#result2})"
# 測(cè)試字符串替換性能
echo ""
echo "2. 字符串替換性能測(cè)試:"
test_string=$(printf '%*s' $((iterations/10)) | tr ' ' 'xabcdefghij')
# 方法1:使用 ${var//pattern/replacement}
start_time=$(date +%s%N)
result3=${test_string//a/A}
end_time=$(date +%s%N)
time3=$((end_time - start_time))
echo " ${} 語(yǔ)法: ${time3:0:-6}ms"
# 方法2:使用 sed
start_time=$(date +%s%N)
result4=$(echo "$test_string" | sed 's/a/A/g')
end_time=$(date +%s%N)
time4=$((end_time - start_time))
echo " sed命令: ${time4:0:-6}ms"
# 測(cè)試字符串分割性能
echo ""
echo "3. 字符串分割性能測(cè)試:"
delimiter_string=$(printf 'a,b,c,d,e,f,g,h,i,j,'%.0s {1..1000})
# 方法1:使用 IFS
start_time=$(date +%s%N)
OLD_IFS=$IFS
IFS=','
read -ra arr5 <<< "$delimiter_string"
IFS=$OLD_IFS
end_time=$(date +%s%N)
time5=$((end_time - start_time))
echo " IFS方法: ${time5:0:-6}ms (數(shù)組長(zhǎng)度: ${#arr5[@]})"
# 方法2:使用 cut
start_time=$(date +%s%N)
arr6=()
i=1
while [ $i -le 10000 ]; do
element=$(echo "$delimiter_string" | cut -d',' -f$i)
[ -z "$element" ] && break
arr6+=("$element")
((i++))
done
end_time=$(date +%s%N)
time6=$((end_time - start_time))
echo " cut命令: ${time6:0:-6}ms (數(shù)組長(zhǎng)度: ${#arr6[@]})"
}
# 運(yùn)行性能測(cè)試
performance_test
渲染錯(cuò)誤: Mermaid 渲染失敗: Parse error on line 8: ...組join] D --> H[${} 語(yǔ)法] D --> I[s ----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'DIAMOND_START'
Java 對(duì)比示例:
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class AdvancedStringHandling {
public static void processMultilineString() {
// 創(chuàng)建多行字符串
String multilineText = "第一行文本\n" +
"第二行包含特殊字符 !@#$%^&*\n" +
"第三行數(shù)字 123456\n" +
"第四行混合內(nèi)容 abc123XYZ\n" +
"第五行結(jié)束文本";
System.out.println("=== 多行字符串處理 ===");
System.out.println("原始文本:");
System.out.println(multilineText);
System.out.println();
// 按行分割處理
System.out.println("按行處理:");
String[] lines = multilineText.split("\n");
for (int i = 0; i < lines.length; i++) {
System.out.println("第" + (i + 1) + "行: '" + lines[i] + "'");
}
System.out.println();
// 統(tǒng)計(jì)行數(shù)
System.out.println("總行數(shù): " + lines.length);
// 提取特定行
if (lines.length >= 2) {
System.out.println("第二行: " + lines[1]);
}
// 處理每行(去除空格、轉(zhuǎn)換大小寫等)
System.out.println();
System.out.println("處理后的文本:");
for (String line : lines) {
// 去除首尾空格
String trimmed = line.trim();
// 轉(zhuǎn)換為大寫
String upper = trimmed.toUpperCase();
System.out.println(upper);
}
}
public static void handleEncoding() throws Exception {
System.out.println("=== 字符串編碼處理 ===");
// 創(chuàng)建包含中文的測(cè)試文本
String chineseText = "你好,世界!Hello, World!";
System.out.println("原始文本: " + chineseText);
// UTF-8編碼(Java默認(rèn))
byte[] utf8Bytes = chineseText.getBytes(StandardCharsets.UTF_8);
String utf8Text = new String(utf8Bytes, StandardCharsets.UTF_8);
System.out.println("UTF-8編碼: " + utf8Text);
// URL編碼
String urlEncoded = URLEncoder.encode(chineseText, StandardCharsets.UTF_8);
System.out.println("URL編碼: " + urlEncoded);
// URL解碼
String urlDecoded = URLDecoder.decode(urlEncoded, StandardCharsets.UTF_8);
System.out.println("URL解碼: " + urlDecoded);
}
// 簡(jiǎn)單的模板引擎實(shí)現(xiàn)
public static class TemplateEngine {
public static String process(String template, Object... params) {
System.out.println("=== 模板引擎 ===");
System.out.println("模板: " + template);
System.out.println("參數(shù): " + Arrays.toString(params));
System.out.println();
String result = template;
// 替換 {0}, {1}, {2}... 格式的占位符
for (int i = 0; i < params.length; i++) {
if (params[i] instanceof String && ((String)params[i]).contains("=")) {
continue; // 跳過(guò)命名參數(shù)
}
String placeholder = "{" + i + "}";
result = result.replace(placeholder, String.valueOf(params[i]));
}
// 替換 {name} 格式的命名占位符
Map<String, String> namedParams = new HashMap<>();
for (Object param : params) {
if (param instanceof String && ((String)param).contains("=")) {
String[] parts = ((String)param).split("=", 2);
namedParams.put(parts[0], parts[1]);
}
}
for (Map.Entry<String, String> entry : namedParams.entrySet()) {
String placeholder = "{" + entry.getKey() + "}";
result = result.replace(placeholder, entry.getValue());
}
System.out.println("結(jié)果: " + result);
return result;
}
}
public static void performanceTest() {
int iterations = 10000;
System.out.println("=== 字符串操作性能測(cè)試 (" + iterations + " 次迭代) ===");
// 測(cè)試字符串連接性能
System.out.println("1. 字符串連接性能測(cè)試:");
// 方法1:使用 += 操作符
long startTime = System.nanoTime();
String result1 = "";
for (int i = 0; i < iterations; i++) {
result1 += "a";
}
long endTime = System.nanoTime();
long time1 = (endTime - startTime) / 1000000;
System.out.println(" += 操作符: " + time1 + "ms (長(zhǎng)度: " + result1.length() + ")");
// 方法2:使用 StringBuilder
startTime = System.nanoTime();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < iterations; i++) {
sb.append("a");
}
String result2 = sb.toString();
endTime = System.nanoTime();
long time2 = (endTime - startTime) / 1000000;
System.out.println(" StringBuilder: " + time2 + "ms (長(zhǎng)度: " + result2.length() + ")");
// 測(cè)試字符串替換性能
System.out.println();
System.out.println("2. 字符串替換性能測(cè)試:");
char[] testChars = new char[iterations / 10];
Arrays.fill(testChars, 'x');
for (int i = 0; i < testChars.length; i++) {
testChars[i] = "abcdefghij".charAt(i % 10);
}
String testString = new String(testChars);
// 方法1:使用 replaceAll
startTime = System.nanoTime();
String result3 = testString.replaceAll("a", "A");
endTime = System.nanoTime();
long time3 = (endTime - startTime) / 1000000;
System.out.println(" replaceAll: " + time3 + "ms");
// 方法2:使用 StringBuilder 手動(dòng)替換
startTime = System.nanoTime();
StringBuilder sb2 = new StringBuilder();
for (char c : testString.toCharArray()) {
sb2.append(c == 'a' ? 'A' : c);
}
String result4 = sb2.toString();
endTime = System.nanoTime();
long time4 = (endTime - startTime) / 1000000;
System.out.println(" StringBuilder手動(dòng): " + time4 + "ms");
// 測(cè)試字符串分割性能
System.out.println();
System.out.println("3. 字符串分割性能測(cè)試:");
StringBuilder delimiterBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
delimiterBuilder.append("a,b,c,d,e,f,g,h,i,j,");
}
String delimiterString = delimiterBuilder.toString();
// 方法1:使用 split
startTime = System.nanoTime();
String[] arr5 = delimiterString.split(",");
endTime = System.nanoTime();
long time5 = (endTime - startTime) / 1000000;
System.out.println(" split方法: " + time5 + "ms (數(shù)組長(zhǎng)度: " + arr5.length + ")");
// 方法2:使用 StringTokenizer(傳統(tǒng)方法)
startTime = System.nanoTime();
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(delimiterString, ",");
String[] arr6 = new String[tokenizer.countTokens()];
int index = 0;
while (tokenizer.hasMoreTokens()) {
arr6[index++] = tokenizer.nextToken();
}
endTime = System.nanoTime();
long time6 = (endTime - startTime) / 1000000;
System.out.println(" StringTokenizer: " + time6 + "ms (數(shù)組長(zhǎng)度: " + arr6.length + ")");
}
public static void main(String[] args) throws Exception {
// 測(cè)試多行字符串處理
processMultilineString();
System.out.println();
// 測(cè)試編碼處理
handleEncoding();
System.out.println();
// 測(cè)試模板引擎
TemplateEngine.process("Hello {0}, welcome to {1}!", "John", "Java Programming");
System.out.println();
TemplateEngine.process("用戶 {name} 在 {time} 登錄系統(tǒng),IP地址: {ip}",
"name=張三", "time=2024-01-15 14:30:25", "ip=192.168.1.100");
System.out.println();
TemplateEngine.process("訂單號(hào): {order_id}, 商品: {product}, 數(shù)量: {quantity}, 總價(jià): ¥{price}",
"order_id=ORD2024001", "product=筆記本電腦", "quantity=1", "price=8999.00");
System.out.println();
// 運(yùn)行性能測(cè)試
performanceTest();以上就是Shell腳本中字符串處理的實(shí)用技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Shell腳本字符串處理技巧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
shell腳本批量執(zhí)行指定路徑下sql腳本的實(shí)現(xiàn)
本文主要介紹了shell腳本批量執(zhí)行指定路徑下sql腳本的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
用來(lái)檢測(cè)輸入的選項(xiàng)$1是否在PATH中的shell腳本
今天無(wú)意中發(fā)現(xiàn)一本挺有意思的shell編程的書(shū),是e文的,內(nèi)容是101個(gè)shell案例,堅(jiān)持明天看一個(gè),寫點(diǎn)心得2016-08-08
shell查找當(dāng)前目錄下大于1M的文件的三種方法分享
查找當(dāng)前目錄下大于1M的文件的三種方法,有需要的朋友可以參考下2013-02-02
shell編程之實(shí)現(xiàn)windows回收站功能分享
這篇文章主要介紹了使用trash命令替代linux rm命令實(shí)現(xiàn)windows回收站的功能,需要的朋友可以參考下2014-03-03
關(guān)于ssh連不上問(wèn)題的解決方法(必看)
下面小編就為大家?guī)?lái)一篇關(guān)于ssh連不上問(wèn)題的解決方法(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03

