最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Shell腳本中字符串處理的實(shí)用技巧分享

 更新時(shí)間:2026年03月23日 09:50:06   作者:Jinkxs  
在 Linux 系統(tǒng)管理和自動(dòng)化運(yùn)維的世界中,Shell 腳本是不可或缺的工具,而字符串處理,則是 Shell 編程中最常用、最核心的功能之一,本文將深入探討 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)文章

  • bash腳本輸入密碼不回顯問(wèn)題的解決方法

    bash腳本輸入密碼不回顯問(wèn)題的解決方法

    編寫一個(gè)bash腳本時(shí),需要用戶輸入一個(gè)密碼,方可繼續(xù)后續(xù)流程,但是又要保證用戶輸入的密碼不會(huì)被別人看到,因此排除了通過(guò)參數(shù)將密碼傳入腳本的方案
    2013-08-08
  • shell腳本批量執(zhí)行指定路徑下sql腳本的實(shí)現(xià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
  • 詳解Linux中的awk命令

    詳解Linux中的awk命令

    awk是一個(gè)強(qiáng)大的文本分析工具,相對(duì)于grep的查找,sed的編輯,awk在其對(duì)數(shù)據(jù)分析并生成報(bào)告時(shí),顯得尤為強(qiáng)大。這篇文章主要介紹了Linux中的awk命令的相關(guān)知識(shí),需要的朋友可以參考下
    2019-11-11
  • 用來(lái)檢測(cè)輸入的選項(xiàng)$1是否在PATH中的shell腳本

    用來(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的文件的三種方法分享

    shell查找當(dāng)前目錄下大于1M的文件的三種方法分享

    查找當(dāng)前目錄下大于1M的文件的三種方法,有需要的朋友可以參考下
    2013-02-02
  • shell編程之實(shí)現(xiàn)windows回收站功能分享

    shell編程之實(shí)現(xiàn)windows回收站功能分享

    這篇文章主要介紹了使用trash命令替代linux rm命令實(shí)現(xiàn)windows回收站的功能,需要的朋友可以參考下
    2014-03-03
  • Linux下服務(wù)器重啟的腳本命令

    Linux下服務(wù)器重啟的腳本命令

    Linux關(guān)閉和重啟系統(tǒng)一般使用相同的命令可以實(shí)現(xiàn)。下面腳本之家小編給大家?guī)?lái)了Linux下服務(wù)器重啟的腳本命令,感興趣的朋友一起看看吧
    2017-09-09
  • linux中&和&&,|和||及分號(hào)(;)的用法

    linux中&和&&,|和||及分號(hào)(;)的用法

    本文主要介紹了linux中&和&&,|和||及分號(hào)(;)的用法,我們經(jīng)常會(huì)用到,但是很多人會(huì)混淆,下面就來(lái)介紹一下具體用法,鞏固的大家的記憶,感興趣的可以了解一下
    2023-06-06
  • 關(guān)于ssh連不上問(wèn)題的解決方法(必看)

    關(guān)于ssh連不上問(wèn)題的解決方法(必看)

    下面小編就為大家?guī)?lái)一篇關(guān)于ssh連不上問(wèn)題的解決方法(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Ubuntu中的sudo和su命令介紹

    Ubuntu中的sudo和su命令介紹

    這篇文章介紹了Ubuntu中的sudo和su命令,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06

最新評(píng)論

苗栗市| 江川县| 陕西省| 石泉县| 延津县| 麻栗坡县| 宜川县| 莱西市| 张家港市| 静安区| 嘉善县| 武隆县| 丹寨县| 永仁县| 奉节县| 平邑县| 九台市| 靖边县| 安吉县| 类乌齐县| 勐海县| 松潘县| 安化县| 离岛区| 吉首市| 西贡区| 启东市| 灵山县| 延川县| 柳河县| 钟祥市| 盐源县| 台湾省| 平泉县| 霍林郭勒市| 永年县| 宁城县| 驻马店市| 大姚县| 湛江市| 株洲市|