awk进阶指南:从基础语法到自定义函数,解锁文本处理的全新姿势

awk实战技巧:从基础到高级的文本处理指南 本文是一份全面的awk实战指南,从基础语法、内置变量、条件匹配讲起,逐步深入到变量计算、流程控制、数组应用等高级技巧。通过大量实例,如日志分析、数据统计和格式化报告,展示了awk作为文本处理瑞士军刀在Linux/Unix环境下的强大能力,帮助开发者和运维人员高效处理各类文本数据。 阅读详情

awk进阶指南:从基础语法到自定义函数,解锁文本处理的全新姿势

如果你已经能熟练地用 awk '{print $1}' 来提取日志的第一列,或者用简单的条件过滤数据,那么恭喜你,你已经迈入了命令行文本处理的大门。但你是否曾好奇,为什么有些人的awk脚本简洁得如同诗行,而自己的却冗长笨拙?是否在处理复杂的数据汇总时,感到力不从心,只能求助于更重的编程语言?awk远不止是一个“字段提取器”,它是一门完整的、图灵完备的编程语言,沉睡在每一个Linux/Unix系统中,等待着被真正唤醒。

这篇文章是为那些希望将awk从“好用的小工具”升级为“得心应手的瑞士军刀”的开发者准备的。我们将抛开那些零散的命令片段,从语言设计的视角,重新审视awk。你会发现,通过变量、数组、流程控制和函数,你能用几十行脚本完成以往需要编写Python或Perl脚本的任务,而且速度往往更快。无论是实时日志分析、复杂数据报表生成,还是系统状态监控,awk都能提供一种独特而高效的解决方案。让我们开始这场深度探索,解锁文本处理的更高阶姿势。

1. 重塑认知:将awk视为一门语言

许多开发者对awk的认知停留在命令行单行命令的层面,这极大地限制了其能力的发挥。要进阶,第一步是思维模式的转变:awk是一门解释型、数据驱动的编程语言。

1.1 程序结构与执行模型

一个完整的awk程序遵循一个清晰的结构,这个结构是其高效处理流式数据的核心。

BEGIN { <初始化操作> }
<模式1> { <动作1> }
<模式2> { <动作2> }
...
END { <汇总操作> }

执行流程:

  1. BEGIN块(可选):在读取任何输入行之前执行一次。常用于初始化变量、打印表头。
  2. 主循环:对于输入数据的每一行(记录),awk会依次检查所有模式。如果某行匹配某个模式,则执行其对应的动作。如果没有指定模式,则默认匹配所有行。
  3. END块(可选):在处理完所有输入行之后执行一次。常用于输出最终统计结果。

提示:理解这个“隐式循环”是编写高效awk脚本的关键。你不需要写for line in file,awk自动为你做了。

1.2 记录与字段:数据模型的基石

awk将输入数据视为由记录组成的流,每条记录又由字段构成。默认情况下:

  • 记录分隔符 (RS):换行符 \n。一条记录就是一行。
  • 字段分隔符 (FS):空格或制表符。一个字段就是一列。

但这两个分隔符是完全可配置的,这赋予了awk处理非标准格式数据的能力。

# 示例:处理以分号分隔的CSV文件(假设字段内无引号包裹的逗号)
awk -F';' '{print "第一个字段是:", $1}' data.csv

# 示例:处理以空行分隔的多段文本(如某些配置文件)
awk -v RS="" '{print "段落", NR, "有", NF, "个字段"}' multi_block.txt

内置变量速查表:

变量含义典型用途
$0当前完整的输入记录(整行)打印或处理整行内容
$1, $2, ... $NF当前记录的第1、2...到最后一个字段访问特定列的数据
NFNumber of Fields,当前记录的字段数print $NF 打印最后一列
NRNumber of Records,已读记录的总数(行号)打印带行号的内容
FNR当前文件的记录号,处理多个文件时会为每个文件重置分别统计多个文件的行数
FS输入Field Separator,字段分隔符-F: 等同于 -v FS=":"
OFS输出Field Separator,输出时字段间的分隔符-v OFS="\t" 使输出以制表符分隔
RS输入Record Separator,记录分隔符处理非行格式的数据
ORS输出Record Separator,输出时记录间的分隔符控制输出行的结尾符

2. 掌握核心语法:变量、运算与流程控制

一旦理解了数据模型,下一步就是学习如何操作数据。awk的语法借鉴了C语言,对于有编程经验的开发者来说非常亲切。

2.1 变量:灵活的数据容器

awk变量无需声明,直接赋值即可使用。根据上下文,它们可以是数字或字符串。

# 在BEGIN块中定义和使用变量
awk 'BEGIN {
    greeting = "Hello, World"
    count = 10
    price = 9.99
    total = count * price
    print greeting, "总价是:", total
}'

变量作用域:在awk中,变量默认是全局的(除了函数参数)。这意味着在一个模式{动作}中赋值的变量,可以在后续的模式动作块或END块中访问。

# 统计文件中包含“error”关键词的行数
awk '/error/ {error_count++} END {print "发现错误数:", error_count}' app.log

2.2 丰富的运算符

awk支持完整的算术、比较、逻辑、赋值和三元运算符。

  • 算术:+, -, *, /, % (取模), ^或** (幂运算)
  • 比较:==, !=, >, <, >=, <=
  • 逻辑:&& (与), || (或), ! (非)
  • 匹配:~ (匹配正则), !~ (不匹配正则)
  • 三元运算符:条件 ? 表达式1 : 表达式2
# 使用三元运算符进行条件赋值
awk '{status = ($3 > 80) ? "过高" : "正常"; print $1, "状态:", status}' server_load.txt

2.3 流程控制:if-else与循环

awk提供了完整的流程控制语句,让你能实现复杂的逻辑。

if-else if-else 语句:

# 根据成绩分级
awk -F, '{
    if ($2 >= 90) grade = "A";
    else if ($2 >= 80) grade = "B";
    else if ($2 >= 70) grade = "C";
    else if ($2 >= 60) grade = "D";
    else grade = "F";
    print $1, "的成绩等级是:", grade
}' scores.csv

循环语句: awk支持for, while, do...while循环,以及break, continue控制语句。

# 使用for循环逆序打印一行中的所有字段
awk '{
    printf "行 %d 逆序字段: ", NR
    for (i = NF; i >= 1; i--) {
        printf "%s ", $i
    }
    printf "\n"
}' data.txt

3. 解锁高级数据结构:数组的魔力

数组是awk中最强大、最独特的特性之一。它们是关联数组,下标可以是数字或字符串,这为数据分组和统计提供了极大的便利。

3.1 关联数组的基本操作

# 创建并访问关联数组
awk 'BEGIN {
    user["name"] = "Alice"
    user["age"] = 30
    user["city"] = "New York"
    print "用户", user["name"], "来自", user["city"]
}'

3.2 实战:数据分组与频率统计

这是awk数组最经典的应用场景。假设我们有一个网站访问日志,第一列是IP地址,我们想统计每个IP的访问次数。

# 示例日志格式: 192.168.1.1 - - [10/Apr/2023:12:34:56] "GET /index.html HTTP/1.1" 200 1234
awk '{ ip_count[$1]++ } END { for (ip in ip_count) print ip, ip_count[ip] }' access.log

代码解读:

  1. ip_count[$1]++:以第一列(IP地址)作为数组ip_count的下标。每次遇到一个IP,该IP对应的值就加1。如果这个IP第一次出现,awk会自动创建该元素并初始化为0,然后自增为1。
  2. END { ... }:处理完所有行后,遍历ip_count数组,打印每个IP及其出现次数。

3.3 多维数组模拟与复杂统计

awk本身不支持真正的多维数组,但可以通过拼接下标来模拟。例如,统计每个小时(hour)每个状态码(status)出现的次数。

# 假设日志第4列是时间,第9列是HTTP状态码
awk '{
    # 从时间字段中提取小时,例如从[10/Apr/2023:12:34:56]中提取“12”
    split($4, time_parts, ":")
    hour = time_parts[2]
    # 拼接小时和状态码作为数组下标
    stats[hour, $9]++
}
END {
    printf "%-5s %-5s %s\n", "Hour", "Code", "Count"
    for (key in stats) {
        # 分割复合键
        split(key, sep, SUBSEP) # SUBSEP是下标分隔符,默认为“\034”
        printf "%-5s %-5s %d\n", sep[1], sep[2], stats[key]
    }
}' access.log | sort -n

注意:遍历关联数组(for (key in array))的顺序是不确定的。如果需要有序输出,通常有两种方法:1) 将结果通过管道传递给sort命令;2) 使用asort()或asorti()函数对数组值或下标进行排序(GNU awk支持)。

4. 内置函数与自定义函数:构建可复用工具集

awk内置了丰富的函数库,涵盖了数学计算、字符串处理、时间操作和I/O控制。更重要的是,你可以定义自己的函数,将常用逻辑模块化。

4.1 不可或缺的字符串函数

文本处理离不开字符串操作。以下是一些最常用的函数:

  • length(string):返回字符串长度。
  • index(haystack, needle):返回子串needle在haystack中首次出现的位置,未找到则返回0。
  • substr(string, start, length):从string的start位置开始截取length个字符的子串。
  • split(string, array, separator):用separator将string分割,并存入array。数组下标从1开始。
  • gsub(regex, replacement, target):在target中,将匹配正则表达式regex的所有部分替换为replacement。如果省略target,则默认为$0。
  • match(string, regex):返回regex在string中匹配到的位置,并设置RSTART和RLENGTH两个内置变量。
# 示例:清洗数据,将字段中所有多余的空格替换为单个空格
awk '{
    # gsub是全局替换,这里匹配一个或多个连续空格,替换为一个空格
    gsub(/[[:space:]]+/, " ", $0)
    print
}' messy_data.txt

# 示例:从URL中提取域名
awk '{
    # 匹配“://”之后到下一个“/”之前的部分
    if (match($0, /:\/\/([^\/]+)/, parts)) {
        print "域名:", parts[1]
    }
}' url_list.txt # 注意:match的第三个参数`parts`数组是GNU awk的扩展功能

4.2 数值与时间函数

  • int(num):取整。
  • rand():返回0到1之间的随机数。
  • srand([seed]):设置随机数种子。
  • systime():返回当前时间的时间戳(自1970年以来的秒数)。
  • strftime(format, timestamp):将时间戳格式化为字符串(GNU awk功能强大)。
# 生成10个1-100之间的随机整数
awk 'BEGIN { srand(); for(i=1; i<=10; i++) print int(rand()*100)+1 }'

# 格式化输出当前时间
awk 'BEGIN { print strftime("今天是 %Y年%m月%d日,%H时%M分%S秒", systime()) }'

4.3 创建自定义函数

当你的脚本逻辑变得复杂时,自定义函数能极大地提高代码的可读性和复用性。函数定义通常放在BEGIN块之前或脚本文件的开头。

语法:

function 函数名(参数1, 参数2, ..., 局部变量) {
    # 函数体
    # 可以使用return返回值
    return 结果
}

实战案例:编写一个函数,将字节数转换为易读的格式(KB, MB, GB)。

# 保存为 format_bytes.awk 文件
function format_bytes(bytes) {
    # 在函数参数后面声明局部变量
    local units[4] = {"B", "KB", "MB", "GB"}
    local i = 0
    while (bytes >= 1024 && i < 3) {
        bytes /= 1024
        i++
    }
    # 使用 sprintf 格式化输出,保留两位小数
    return sprintf("%.2f %s", bytes, units[i])
}

# 主程序
{
    # 假设第5列是文件大小(字节)
    printf "文件名: %-20s 大小: %s\n", $9, format_bytes($5)
}

然后在命令行中使用:

ls -l | awk -f format_bytes.awk

这个例子展示了如何将业务逻辑封装成函数,使得主程序清晰简洁。local关键字(GNU awk支持)用于声明局部变量,避免污染全局命名空间。

5. 性能调优与最佳实践

写出能跑的awk脚本不难,但写出高效、优雅的脚本则需要一些技巧。

5.1 减少不必要的操作

  • 尽早过滤:在模式部分进行筛选,比在动作里用if判断更高效。
    # 更优:模式匹配
    awk '/error/ && $6 == "CRITICAL" {criticals++} END {print criticals}' app.log
    # 次优:动作内判断
    awk '{if ($0 ~ /error/ && $6 == "CRITICAL") criticals++} END {print criticals}' app.log
    
  • 避免重复计算:对于一行内多次使用的值,可以先保存到变量中。
    # 优化前
    awk '{print $3, $3 * 1.08, $3 * 0.92}' prices.txt
    # 优化后
    awk '{price = $3; print price, price * 1.08, price * 0.92}' prices.txt
    

5.2 选择合适的数据结构

  • 对于简单的键值计数,关联数组是无敌的。
  • 如果需要保持顺序,可以考虑使用for (i=1; i<=NR; i++)的循环配合传统数字下标数组,或者使用GNU awk的asorti()对关联数组下标排序后再遍历。

5.3 利用getline进行精细控制

getline函数让你可以手动控制读取过程,用于处理多行组成一条记录等复杂情况。

# 处理一种特殊的配置文件,节(section)由空行分隔
awk -v RS="" '{  # RS="" 使awk以空行作为记录分隔符
    print "处理节:", NR
    print $0  # $0现在包含整个节的内容
    print "---"
}' config.ini

5.4 将复杂脚本写入文件

对于超过一行的逻辑,强烈建议将脚本写入.awk文件,然后通过-f选项调用。这便于维护、调试和复用。

# 脚本文件 complex_analysis.awk
BEGIN {
    print "开始分析..."
    FS=","
}
$2 > 100 { large_transactions++ }
END {
    print "分析完成。"
    print "大额交易数量:", large_transactions
}

# 命令行调用
awk -f complex_analysis.awk transaction_data.csv

6. 综合实战:从日志分析到数据清洗

让我们用一个综合案例来结束本次进阶之旅。假设我们有一个简化的应用程序日志文件 app.log,格式如下:

2023-10-27 14:30:01 [INFO] User alice logged in from 192.168.1.100
2023-10-27 14:35:22 [ERROR] Database connection failed. Module: auth
2023-10-27 14:35:25 [WARN] High memory usage detected: 85%
2023-10-27 14:40:10 [INFO] User bob logged in from 192.168.1.150
2023-10-27 14:45:33 [ERROR] File not found: /var/www/data.txt. Module: web

目标:编写一个awk脚本,实现以下功能:

  1. 统计不同日志级别(INFO, WARN, ERROR)的数量。
  2. 提取所有ERROR日志的模块名称。
  3. 找出登录最频繁的用户。

解决方案:

# 保存为 log_analyzer.awk
BEGIN {
    print "=== 应用程序日志分析报告 ==="
    print ""
}

# 1. 统计日志级别
{
    # 匹配类似 [INFO] 的部分
    if (match($0, /\[([A-Z]+)\]/, level_parts)) {
        log_level = level_parts[1]
        level_count[log_level]++
    }
}

# 2. 提取ERROR日志的模块
/\[ERROR\]/ {
    # 匹配 “Module: xxx” 模式
    if (match($0, /Module: ([a-z]+)/, module_parts)) {
        error_module = module_parts[1]
        # 记录该模块出现的错误次数
        module_error_count[error_module]++
        # 也可以将具体的错误信息保存起来
        error_messages[error_module, module_error_count[error_module]] = $0
    }
}

# 3. 统计用户登录
/ logged in from / {
    # 匹配 “User xxx logged in” 模式
    if (match($0, /User ([a-z]+) logged in/, user_parts)) {
        username = user_parts[1]
        user_login_count[username]++
    }
}

END {
    # 输出第一部分:级别统计
    print "1. 日志级别分布:"
    for (level in level_count) {
        printf "   %-6s: %d 条\n", level, level_count[level]
    }
    print ""

    # 输出第二部分:错误模块统计
    print "2. ERROR日志模块分布:"
    if (length(module_error_count) == 0) {
        print "   本次分析未发现ERROR日志。"
    } else {
        for (module in module_error_count) {
            printf "   模块 '%-10s': %d 个错误\n", module, module_error_count[module]
        }
    }
    print ""

    # 输出第三部分:最活跃用户
    print "3. 用户登录频率:"
    if (length(user_login_count) == 0) {
        print "   本次分析未发现登录记录。"
    } else {
        # 找出登录次数最多的用户(简单的线性查找)
        max_login = 0
        top_user = ""
        for (user in user_login_count) {
            if (user_login_count[user] > max_login) {
                max_login = user_login_count[user]
                top_user = user
            }
        }
        printf "   最活跃用户是 '%s',登录了 %d 次。\n", top_user, max_login
    }
    print ""
    print "=== 分析结束 ==="
}

运行脚本:

awk -f log_analyzer.awk app.log

这个脚本融合了模式匹配、正则表达式捕获组、关联数组统计、条件判断和字符串处理,是一个典型的、中等复杂度的awk应用。它没有使用任何外部命令,仅凭awk自身就完成了一份结构化的分析报告。

通过这样的深度探索,你会发现,awk不再是一个简单的命令行过滤器,而是一个能够独立解决复杂文本处理问题的强大工具。它的魅力在于,在看似简单的语法背后,隐藏着处理数据流的高效与优雅。下次当你面对一堆需要提取、转换、汇总的文本数据时,不妨先问问自己:“用awk会不会更简单?”

『忘了再学』Shell基础 — 27、AWK编程的介绍和基本使用 目录* 1、AWK介绍 + (1)AWK概述 + (2)格式化输出 + (3)命令说明AWK是一种处理文本文件的语言,是一个强大的文本分析工具。AWK可以看成一门独立的语言,它拥有语言的基本特征,换句话说AWK可以写出极其繁琐和复杂的程序,AWK的语法比Shell的语法还难以接收。但绝大多数情况下,我们并不需要用AWK写过于复杂的东西,建议能用Shell处理的需求就不用AWK来解决。当用AWK处理需求远要比Shell处理简单的多的时候,我们就用AWK来解决。AWK也是用来截取列信息的,它比Shell中的命令 阅读详情

相关推荐

Ubuntu零基础入门到精通【6.7讲】:文本处理三剑客:grep、sed、awk 从入门到实战!

🏆 本文收录于 《滚雪球学 Ubuntu》 专栏。该本专栏面向有一定计算机基础,但尚未系统学习 Linux / Ubuntu 的读者,采用“滚雪球式学习法”:先装好、再会用、再理解、再优化、再实战,带你从第一次进入 Ubuntu 桌面 / 终端开始,逐步掌握 Ubuntu 的日常使用、命令操作、软件安装、系统配置、开发环境搭建与服务器部署能力。

**My Coding Family** 1992

One True Awk完全教程:从基础语法到高级应用

One True Awk是一款轻量级且功能强大的文本处理工具,作为经典的awk实现,它以简洁的语法和高效的文本处理能力深受开发者喜爱。本教程将带您从基础语法开始,逐步掌握One True Awk的核心功能与高级应用技巧,让您轻松应对各种文本处理任务。 ## 一、One True Awk简介:为什么选择这款文本处理神器? One True Awk源自Unix传统的文本处理工具链,以其"简洁而不简

gitblog_00482的博客 903

掌握awk内置变量ARGC与ARGV的应用

本文深入探讨awk语言中ARGC和ARGV内置变量的使用方法和场景。ARGC用于存储传递给awk程序的参数数量,ARGV是一个数组,包含了这些参数。通过示例演示如何利用这些变量控制awk程序的行为,包括读取不同的输入文件和处理命令行选项。此外,还介绍了如何在BEGIN规则中处理ARGV数组以筛选和删除命令行选项,以及如何模拟多维数组和数组排序。

weixin_29903713的博客 439

Sed & Awk 第二版资源文件——解锁文本处理的利器

Sed & Awk 第二版资源文件——解锁文本处理的利器 【下载地址】SedAwk第二版资源文件介绍 《Sed & Awk, 2nd edition》是一本深入探讨 `sed` 和 `awk` 命令的权威指南,专为希望提升文本处理技能的用户设计。本书提供英文原版内容,确保读者能够原汁原味地学习这两款强大工具的使用...

gitblog_06725的博客 649

基于Zemax的干涉仪仿真——Fizeau球面干涉仪

最近在用Zemax仿真干涉仪,在这之前查资料都是关于一些平面干涉仪的仿真,很少有关于Fizeau型的,尤其是球面干涉仪的仿真,看到很多关于这方面的问题回复都说利用多重结构仿照Zemax马赫-泽德干涉仪去做,但是也没有具体的过程,因此在这里分享一下我仿真的干涉仪步骤方法,具体是利用多重结构完成的仿真。

weixin_46657737的博客 6410

(实战)[re:Invent 2018]-001:赛道分析-(致敬1024)

打印log

Rainbow 2784

掌握AWK:文本处理的瑞士军刀

深入了解 AWK,这个文本处理的利器,为您的数据处理任务带来便利。本文将带您穿越 AWK 的基本语法,学习如何利用模式匹配、条件语句和内置函数高效地处理文本数据。探索 AWK 强大的数学运算和循环结构,同时了解如何删除重复行和输出自定义字段。通过示例,您将发现 AWK 的强大功能,助您轻松处理各种文本文件,从而提高工作效率。

欢迎来到技术蜜糖罐的IT角落! 1万+

Infinite-Canvas:一站式AI绘画工作流平台部署与实战指南

在 AI 绘画和内容创作领域,你是否经常遇到这样的困扰:灵感来了,却要在多个工具间来回切换——找素材、写提示词、调整参数、批量生成,整个过程繁琐且低效。创作一个系列作品时,管理不同版本的图片和提示词更是让人头疼。如果你渴望一个能整合所有流程,实现从素材管理、提示词工程到批量出图一站式完成的工作台,那么今天介绍的 Infinite-Canvas 正是为你量身打造的解决方案。 Infinite-Canvas 是一个开源的本地网页应用,它将 AI 绘画的完整工作流集成在一个界面中。无论你是想快速生成单张图片,还是

weixin_28707535的博客 340

awk 从入门到进阶(中)

在现代数据驱动的场景中,文本数据的处理与分析已成为系统管理、数据分析和开发工作中不可或缺的一部分。从服务器日志的实时解析到大规模数据集的清洗与统计,从配置文件调整到自动化报告生成,高效的文本处理能力直接决定了任务的完成效率与成果质量。作为一款内置于操作系统的文本处理利器,awk不仅能轻松应对日志分析、数据过滤和列操作,还能在数值计算、条件筛选和数据聚合等复杂任务中大显身手。如果说基础篇为你打开了awk的大门,那么本篇中篇将带你深入探索其核心功能。数值计算:从浮点运算到逐行统计,展示awk。

vortex5的博客 1244

ArcMap新手必看:Shape属性中的点ZM值到底是什么?如何快速处理

本文深入解析ArcMap中Shape属性中的点ZM值,揭示其在GIS数据中的隐藏维度作用,包括Z值(高程值)和M值(测量值)。针对ZM值可能引发的服务发布问题,提供三种高效处理方案,帮助新手快速掌握数据导入时的ZM值管控策略及精准去除方法。

weixin_42561476的博客 432

阿里平头哥与华为芯片的比较

阿里平头哥与华为芯片代表了中国AI芯片领域的两种典型发展路径:平头哥通过兼容CUDA生态快速切入市场,以较低成本提供接近国际水平的AI算力;华为则坚持全栈自研路线,构建从芯片到框架的完整技术体系,更注重供应链安全和自主可控。从短期来看,平头哥PPU在单卡性能参数上全面超越昇腾910B,接近英伟达H20水平,且成本优势明显,有望在云服务和互联网应用领域取得更大市场份额。而华为昇腾则凭借全栈自研和端边云协同优势,在政企市场和科研领域更具竞争力。

shao.bing的专栏 4032

awk实战技巧:从基础语法到高级数据处理

本文系统介绍了AWK从基础语法到高级数据处理的实战技巧。AWK作为强大的文本处理工具,其核心在于‘模式-动作’规则,能高效处理日志分析、数据提取和报表生成。文章详细讲解了记录与字段、内置变量、条件判断、循环、关联数组等核心概念,并通过Nginx日志分析、系统监控等真实场景,展示了AWK在数据处理领域的‘瑞士军刀’般的强大能力。

jj890的博客 365

CodeQL查询时遇到报错:A fatal error occurred: Could not process query metadata for...如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1085

探索文本处理的宝藏: Awesome AWK 开源项目推荐

探索文本处理的宝藏: Awesome AWK 开源项目推荐 项目介绍 在文本处理的世界里,有一颗久经考验的明珠——AWK。它以简洁而强大的语法,在数据处理和脚本编写中占据一席之地。今天,我们向您隆重推荐一个汇聚AWK精华的开源项目 —— Awesome AWK。这个项目是由一群AWK热爱者维护的精选资源列表,旨在帮助开发者快速上手并精通AWK语言。 它不仅仅是一份文档清单,更是一个学习与探索的...

gitblog_00058的博客 421

Xiaojie雷达之路---手把手教你从串口获取雷达原始数据(一)---新建工程(开始)

Hello,大家好,我是Xiaojie,欢迎大家能够和Xiaojie来一起学习毫米波雷达知识,Xiaojie准备连载一个系列的文章---利用串口获取毫米波雷达中的原始数据,本系列文章将从新建工程到最后原始数据显示到PC上进行逐步介绍,这个系列的文章大约是一个4-5篇左右。本篇文章呢,主要讲的是如何新建一个毫米波雷达的工程。

XiaoJie的博客 5811

基于信号完整性的PCB设计原则

基于信号完整性的PCB设计建议,以单网络的信号布线作为评估对象,给出了一些最基础的设计指导,如何灵活运用,取决于设计者根据实际场景如何做取舍和判断。

一只豌豆象的博客 1759

iloader iOS 侧载教程:从装上工具到装好第一个 App,3 步跑通

iloader 是一款免费开源的 **iOS 侧载工具**,全程图形化界面,不碰命令行。读完本文,你可以在 Windows、macOS 或 Linux 上装好它,并让自己的 iPhone 完成一次真实侧载:从连上设备、登录 Apple ID,到 SideStore 装进手机。 [![iloader iOS 侧载工具应用图标](https://raw.gitcode.com/GitHub_Tren

gitblog_00714的博客 192

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

进阶篇!Linux 50条进阶指令总结

已经掌握了Linux基础命令?是时候升级你的技能树了!本篇将带你探索Linux的进阶用法,让你从"会用"到"精通"。

一名机电研究生的博客 1067

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

红米AX3000路由器SSH权限完整解锁指南:从基础到进阶的实用教程

想要完全掌控你的红米AX3000路由器吗?厌倦了官方固件的功能限制?通过本文的完整指南,你将学会如何安全解锁路由器的SSH访问权限,获得对设备的完全控制权。无论是安装第三方软件、优化网络性能,还是刷写自定义固件,这篇文章都将为你提供从入门到进阶的实用解决方案。 ## 为什么需要解锁SSH权限? 红米AX3000(也称为AX6)是一款性价比极高的WiFi6路由器,硬件配置相当不错。然而,官方固件

gitblog_00501的博客 522

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

文本管理grep sed awk

本文介绍了Linux系统中文本处理"三剑客":grep、sed和awk的核心用法。grep用于文本搜索,常用参数包括-v(反向选择)、n(显示行号)、r(递归搜索)和E(扩展正则);sed是流编辑器,支持快速批量修改文本,重点讲解了s替换命令和-i直接修改文件的用法;awk擅长结构化文本处理,可指定分隔符(-F)按列提取数据,结合NF变量和正则表达式实现精准过滤。文章通过运维场景实例展示了这些工具的组合应用技巧,并强调生产环境中使用时的注意事项,如避免全盘递归搜索和使用-i.bak备份修改等安全实践。

GALISHIDE的博客 302

Linux进阶教学:从“会用”到“精通”,解锁系统底层核心能力

将常用的复杂命令简化,修改。

Linmonan的博客 439

Linux命令行精粹:从基础到进阶,解锁你的生产力

掌握 Linux 命令行,就像获得一把瑞士军刀。每个工具看似简单,但当你理解其内在联系,并用管道与重定向将它们组织起来时,就能解决复杂问题。希望这篇指南是你探索命令行世界的起点——不断练习、不断组合,让它成为指尖最强大的生产力工具。

greenspan的专栏 924

Oh My Zsh自定义函数终极指南:解锁命令行无限潜力

想要让你的终端体验从普通升级到专业级别吗?🤔 Oh My Zsh自定义函数正是你需要的秘密武器!这个强大的功能可以让你将复杂的命令序列简化为简单的函数调用,大幅提升工作效率。无论你是开发者、系统管理员还是日常用户,掌握自定义函数都能让你的命令行操作如虎添翼。 ## 什么是Oh My Zsh自定义函数? **Oh My Zsh自定义函数**是预定义在Zsh shell中的可重用命令序列,能够将

gitblog_01415的博客 294

Linux tac命令:不只是反向cat,更是文本处理管道的流向转换器

在Linux文本处理领域,数据流操作是核心基础概念。通过管道(pipe)机制,多个命令可以串联形成处理流水线,实现数据的筛选、转换与重组。这种面向流的设计哲学,使得简单工具组合能解决复杂问题,极大提升了命令行效率。tac命令正是这一生态中的关键流向转换器,它通过反转行序或自定义分隔的记录块,改变了数据在管道中的行进方向。这种逆向处理能力,在日志分析、故障排查等需要从最新状态回溯历史的场景中,展现出独特的技术价值。掌握tac与grep、sed、awk等工具的配合,能构建出更优雅的文本处理方案,体现了Linux

weixin_34372728的博客 1007

shell基本命令(四)

详细介绍文本三剑客

always_on_way的博客 1598

Linux Bash 常用操作与历史参数复用

……

u013669912的博客 362
上一篇: MATLAB实战:单脉冲测角和差比幅法仿真全流程(附完整代码)
下一篇: 从零开始:利用Petalinux为Zynq平台构建定制化Linux系统
寂静夜空35
博客等级 码龄3年 59粉丝 1797原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值