R语言之grep函数和正则通配符查询(转载,稍微改动了些数据,用于学习)

本文分享了R语言中使用grep函数结合正则表达式的技巧,包括如何匹配字符串的开始和结束,以及任意字符的搜索,通过实例演示了如何筛选以特定数字开头或结尾的元素。

在R语言的道路上又学到了一个新知识,记下来一起分享!

首先,grep函数可以像数据库查询一样对向量中的具有特定条件的元素进行查询!

其次,介绍几种R语言中的正则通配符:

(1)“^”匹配一个字符串的开始,比如grep("^a","",c("abcd","dcba")),表示将开头为a的字符串。如果要将开头的一个字符串替换,简单地写成“^ab”就行。

Num <- c(3120,4256,3511,4631,4921,4305,5834,3102,3103,5320,3231,4300,3293,3164,3244,3107,3231)
ipn<-grep("^3",Num,value=T)##开头为3的数字##
ipn
 [1] "3120" "3511" "3102" "3103" "3231" "3293" "3164" "3244" "3107" "3231"

  (2)“$”匹配一个字符串的结尾,比如grep("a¥","",c("abcd","dcba")),表示将以a结尾的字符串。如果要将开头的一个字符串替换,简单地写成“^ab”就行。

ipn<-grep("4$",Num,value=T)##以4结尾的的数字#
ipn
[1] "5834" "3164" "3244"

 (3)"."表示除了换行符以外的任一字符,比如grep("a.c","",c("abcd","sdacd"))。

ipn<-grep("3.0",Num,value=T)#include all numbers which includes "3?0"
ipn

 

[1] "3102" "3103" "5320" "4300" "3107"

(暂时先整理到这里,后续再进行补充。。。。。。)

root@NVR:/tmp# tftp -gr test_new_old_database.sh 192.168.0.1 root@NVR:/tmp# ./test_new_old_database.sh 🚀 开始数据库性能测试 📅 Wed Nov 5 09:35:24 UTC 2025 🔍 正在测试: 旧表查询 📌 SQL: SELECT COUNT(*) FROM tZoneInfo; 🔁 执行 5 次... COUNT(*) = 464 sync wal file to db begin! 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 COUNT(*) = 464 sync wal file to db begin! 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 COUNT(*) = 464 sync wal file to db begin! 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 COUNT(*) = 464 sync wal file to db begin! 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 COUNT(*) = 464 sync wal file to db begin! 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 5b5ec808a70990da0e1ead705a431043 📊 旧表查询 测试结果: 平均响应时间: 0.0 ms 最小响应时间: 0.0 ms 最大响应时间: 0.0 ms 总耗时: 0.0 ms 成功次数: 0/5 失败率: 100% 我觉得是ms精度太差了,我的函数应该怎么改#!/bin/sh # ======================================== # 数据库性能测试脚本(纯 sh 兼容版) # 防止 run_query: not found + expr 错误 # ======================================== TRIES=5 VERBOSE=true # ---------------------------------------- # format_ms: 将 scaled_ms (毫秒×1000) 转为字符串 "x.xxx" # 示例: 1234 → "1.234", 1 → "0.001" # ---------------------------------------- format_ms() { micros=$1 case "$micros" in ''|*[!0-9]*) echo "0.000"; return ;; esac millis=$(expr $micros / 1000) # 整数毫秒 sub_ms=$(expr $micros % 1000) # 小数部分(0~999) case $sub_ms in [0-9]) frac="00$sub_ms" ;; [0-9][0-9]) frac="0$sub_ms" ;; *) frac="$sub_ms" ;; esac echo "$millis.${frac#??}" | sed 's/\.\([0-9]\{3\}\).*/.\1/' } # 替换原来的 get_timestamp_us 调用 get_timestamp_us() { local up=$(cat /proc/uptime 2>/dev/null | sed -e 's/[ \t].*//' -e 's/[^0-9.]//g') case "$up" in ''|*[!0-9.]*) echo "0"; return esac local sec frac [ "${up#*.}" != "$up" ] && { sec=${up%%.*}; frac=${up#*.}; } || { sec=$up; frac="0"; } sec=$(echo "$sec" | tr -cd '0-9'); [ -z "$sec" ] && sec=0 frac=$(echo "$frac" | tr -cd '0-9'); [ -z "$frac" ] && frac=0 frac="${frac}000000" frac=${frac:0:6} echo "${sec}${frac}" } # ---------------------------------------- # run_query: 执行 SQL 并返回耗时成功状态 # 输出: "$elapsed_scaled $success" (两个整数) # ---------------------------------------- # 在每次查询后加个极短 sleep(仅用于测试) run_query() { sql_cmd="$1" # --- 记录开始时间 --- start_us=$(get_timestamp_us) case "$start_us" in ''|*[!0-9]*) start_us=0 ;; esac # --- 执行 ubus 命令,并捕获完整输出 --- raw_output=$(ubus call record stg_db_debug "{\"hd_id\":0, \"sql_cmd\":\"$sql_cmd\"}" 2>&1) # --- 记录结束时间 --- end_us=$(get_timestamp_us) case "$end_us" in ''|*[!0-9]*) end_us=0 ;; esac # --- 计算耗时 --- if [ $start_us -gt 0 ] && [ $end_us -gt 0 ] && [ $end_us -ge $start_us ]; then elapsed_micro=$(expr $end_us - $start_us) else # fallback:至少估算 1ms elapsed_micro=1000 fi # --- 判断是否成功 --- # 方法1:检查是否有 COUNT(*) 输出(在 raw_output 中) if echo "$raw_output" | grep -q 'COUNT(*)'; then success=1 else # 方法2:检查是否返回了有效 JSON 且无 error if echo "$raw_output" | grep -q '"result":0\|"message"' || echo "$raw_output" | grep -q '"rows"'; then success=1 else success=0 fi fi # --- 🔥 调试输出:打印每次查询详情 --- printf "DEBUG: Query='%s'\n" "$sql_cmd" printf " Raw Output: %s\n" "$raw_output" printf " Start=%s us, End=%s us → Elapsed=%d us (%.3f ms)\n" \ "$start_us" "$end_us" "$elapsed_micro" "$(echo "scale=3; $elapsed_micro / 1000" | bc 2>/dev/null || echo 0)" printf " Success=%d\n" "$success" echo "" # --- 返回结果 --- echo "$elapsed_micro $success" } # ---------------------------------------- # collect_stats: 收集 N 次查询统计信息 # ---------------------------------------- collect_stats() { label="$1" sql_cmd="$2" i=1 total_time_scaled=0 failed_count=0 min_time="" max_time=0 echo "🔍 正在测试: $label" echo "📌 SQL: $sql_cmd" echo "🔁 执行 $TRIES 次..." while [ $i -le $TRIES ]; do # ✅ 安全调用 run_query output=$(run_query "$sql_cmd") [ -z "$output" ] && output="0 0" set -- $output elapsed_scaled=$1 success=$2 # 防御非数字 case "$elapsed_scaled" in ''|*[!0-9]*) elapsed_scaled=0 ;; esac case "$success" in ''|*[!0-9]*) success=0 ;; esac total_time_scaled=$(expr $total_time_scaled + $elapsed_scaled) if [ "$success" -eq 0 ]; then failed_count=$(expr $failed_count + 1) fi # 更新最小最大值 if [ -z "$min_time" ] || [ $elapsed_scaled -lt $min_time ]; then min_time=$elapsed_scaled fi if [ $elapsed_scaled -gt $max_time ]; then max_time=$elapsed_scaled fi i=$(expr $i + 1) done success_count=$(expr $TRIES - $failed_count) if [ $success_count -gt 0 ]; then avg_scaled=$(expr $total_time_scaled / $success_count) else avg_scaled=0 fi fail_rate=$(expr 100 \* $failed_count / $TRIES) echo "" echo "📊 $label 测试结果:" printf " %-20s %s ms\n" "平均响应时间:" "$(format_ms $avg_scaled)" printf " %-20s %s ms\n" "最小响应时间:" "$(format_ms $min_time)" printf " %-20s %s ms\n" "最大响应时间:" "$(format_ms $max_time)" printf " %-20s %s ms\n" "总耗时:" "$(format_ms $total_time_scaled)" printf " %-20s %d/%d\n" "成功次数:" $success_count $TRIES printf " %-20s %d%%\n" "失败率:" $fail_rate echo "" } # ==================== 主程序 ==================== echo "🚀 开始数据库性能测试" echo "📅 $(date)" # 👇 确保函数已加载后再调用! # 可选:调试函数是否存在 # type run_query || { echo "FATAL: run_query 未定义"; exit 1; } OLD_SQL='SELECT COUNT(*) FROM tZoneInfo;' collect_stats "旧表查询" "$OLD_SQL" echo "✅ 测试完成!"
11-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值