第一个
awk 'FNR <= 3 {if (FNR != 1) printf ","; printf "%s", $0}; END {printf "\n"}' 文件夹路径/*
其中,文件夹路径
指代要处理的文件夹路径。上述命令会遍历该文件夹下所有文件,对于每个文件取前三行,并将这三行组成一行输出。
解释:
FNR <= 3
表示只处理每个文件的前三行。if (FNR != 1) printf ","
表示除了第一行之外,其他行都在前面加上逗号。printf "%s", $0
表示打印当前行的内容。END {printf "\n"}
表示处理完所有文件后,在最后打印一个换行符。
需要注意的是,如果文件名中包含空格或特殊字符,需要使用引号将路径括起来,例如:
awk 'FNR <= 3 {if (FNR != 1) printf ","; printf "%s", $0}; END {printf "\n"}' "文件夹路径/文件名 1" "文件夹路径/文件名 2" ...
前置条件
在 awk
中,可以使用模式(pattern)来指定条件,只有符合条件的行才会进行后续的处理。具体而言,可以在 awk
命令中通过 {}
来包含一个或多个动作(action),如下所示:
awk '/pattern/ { action }' file
其中 /pattern/
是模式,表示需要匹配的字符串或正则表达式,而 { action }
则是动作,表示当匹配到符合模式的行时要执行的操作。如果没有指定模式,则默认匹配所有行。
例如,以下命令会打印 file
文件中以 root
开头的行:
awk '/^root/ { print $0 }' file
在 awk
中还可以使用条件表达式来构建更复杂的条件,例如:
awk '$1 > 50 && $2 < 100 { print $0 }' file
这条命令会打印 file
文件中第一列大于 50 且第二列小于 100 的行。在条件表达式中,$1
和 $2
表示当前行的第一列和第二列,&&
表示逻辑 “与” 操作符。
需要注意的是,在 awk
中,模式和动作是可选的,如果省略了模式,则默认匹配所有行,如果省略了动作,则默认打印匹配到的行。
命令行中使用
可以使用以下命令在 awk
处理结果中前置添加内容:
awk '{print "前置内容" $0}' file
其中,file
是要处理的文件名或路径,$0
表示当前行的全部内容。
例如,以下命令会在 file
文件中每一行前面添加 序号:
后输出:
awk '{print NR ":" $0}' file
这里,NR
表示当前行的行号。如果要在前置内容和行内容之间添加一个分隔符,可以使用如下命令:
awk -v sep='---------' '{print "前置内容" sep $0}' file
其中 -v sep='---------'
表示定义了一个变量 sep
,其值为 '---------'
,即前置内容和行内容之间的分隔符。
需要注意的是,在 awk
中,单引号内的内容不会被 shell 解释,所以对于含有变量的命令,需要使用双引号并用 -v
选项将变量传入 awk
环境中。
配置文件中使用
在 awk
配置文件中,可以使用模式(pattern)来筛选所需的行。模式指定了一个正则表达式,只有匹配该正则表达式的行才会被处理。
例如,以下是一个简单的 awk
配置文件:
/regex_pattern/ {
# 处理匹配到的行
}
其中,regex_pattern
是一个正则表达式,用来匹配要选择的行。大括号内的代码块表示对于匹配到的每一行要执行的命令或操作。代码块中的内容可以包括任意数量的命令或操作,以换行符或分号分隔。
除此之外,awk
还支持多个模式的组合,以及模式与条件表达式的结合,例如:
/pattern1/,/pattern2/ {
# 对于位于 pattern1 和 pattern2 之间的所有行执行命令
}
$1 == "foo" && /bar/ {
# 处理第一列为 "foo" 并且包含 "bar" 的行
}
需要注意的是,在 awk
配置文件中,可以在一行中添加多个命令,但命令必须用分号或换行符进行分隔。某些版本的 awk
还允许在代码块中使用变量和函数。
多个 pattern 逻辑关联
在 awk
中,可以通过设置多个模式(pattern)来确定它们之间的逻辑关系。常用的逻辑操作符有以下三种:
-
逗号
,
:表示并列关系,用于多个模式之间,例如:/pattern1/,/pattern2/ { # 对于位于 pattern1 和 pattern2 之间的所有行执行命令 }
这条命令表示当匹配到
pattern1
时开始执行命令,并一直执行到匹配到pattern2
结束。中间的所有行都将被处理。 -
空格 :表示交集关系,用于同一个模式内部的不同条件表达式之间,例如:
$1 == "foo" && /bar/ { # 处理第一列为 "foo" 并且包含 "bar" 的行 }
这里使用了
&&
逻辑操作符,表示同时满足两个条件才会触发对应的命令或操作。 -
竖线
|
:表示或者关系,用于多个模式之间,例如:/pattern1/ || /pattern2/ { # 对于匹配到 pattern1 或 pattern2 的所有行执行命令 }
这条命令表示只要匹配到
pattern1
或pattern2
中的一个,就执行后续的操作。
需要注意的是,上述逻辑操作符的优先级顺序为:|
> ,
> 空格。在配置多个模式时,可以使用小括号以显式地组织优先级,例如:
(pattern1 || pattern2) && $1 == "foo" {
# 对于匹配到 pattern1 或 pattern2 且第一列为 "foo" 的所有行执行命令
}
这里会先判断 pattern1
和 pattern2
中是否有一个匹配成功,然后再判断第一列是否为 “foo”,最后执行对应的命令。
awk 内置变量
awk
是一种非常强大的文本处理工具,提供了丰富的内置变量和函数,使得在文本处理中能够更加方便和高效地实现各种功能。下面是一些常用的 awk
内置变量:
FS
:字段分隔符,用于指定输入和输出时不同字段之间的分隔符,默认为空格或制表符。NF
:当前行的字段数,即每行中的字段个数。$0
:整个文本行的内容,包括所有字段。$n
:第 n 个字段(从 1 开始),例如$1
表示第一个字段,$2
表示第二个字段,以此类推。NR
:当前处理的行号,从 1 开始递增, 处理多文件时会累积。FNR
:处理多个文件时的行号, 并不会累积。RS
:行分隔符,用于指定输入时每行数据之间的分隔符,默认为换行符。OFS
:输出字段分隔符,用于指定输出时不同字段之间的分隔符,默认为单个空格。ORS
:输出行分隔符,用于指定输出时每行数据之间的分隔符,默认为换行- 符。
这些变量的使用方式非常简单,只需要在 awk
命令中引用即可。例如,使用 $0
可以输出整个文本行的内容:
awk '{print $0}' file.txt
使用 NF
可以获取每行数据中字段的个数:
awk '{print NF}' file.txt
``` `NR` 可以输出当前处理的行号:
awk ‘{print NR}’ file.txt
除了这些常用的变量外,`awk` 还提供了许多其他的内置变量和函数,如 `gsub()`、`substr()` 等,都能够方便地实现各种文本处理任务。
argc argv
在 awk
中,可以使用内置变量 ARGC
和 ARGV
来判断文件是否存在。ARGC
变量表示参数个数,ARGV
数组则表示传入的参数列表,其中第一个元素是命令本身,后面的元素则是指定的文件名。
因此,如果想要判断一个文件是否存在,可以使用以下代码:
awk 'BEGIN {
if (ARGC < 2) {
print "Usage: awk -f script.awk file.txt"
exit
}
filename = ARGV[1]
if (getline < filename <= 0) {
print "File", filename, "does not exist"
exit
}
# process the file here
}' "$@"
上面的代码中,首先使用 if
条件语句判断传入参数的数量是否大于等于 2,如果不足,则输出用法提示信息并退出程序。
然后,将第一个参数(即文件名)赋值给 filename
变量,并使用 getline
函数尝试读取文件的第一行。如果返回结果小于等于 0,说明文件不存在或无法读取,此时输出错误信息并退出程序。如果文件存在,则可以在程序中继续处理该文件。
注意,在 awk
脚本中使用 $0
变量或 getline
函数读取文件内容时,需要在 BEGIN
块之外执行,否则会导致文件未能正确打开或者读取到的行数不正确。
system 命令
在 awk
中,可以使用 shell 命令来删除文件。具体实现方式如下:
awk 'BEGIN {
# 删除指定的文件
system("rm -f file.txt")
}' "$@"
上述代码中,使用 system
函数在 BEGIN
块中执行 shell 命令 rm -f file.txt
,即删除名为 file.txt
的文件。其中,-f
参数表示即使文件不存在也不提示错误信息。
需要注意的是,使用 system
函数执行 shell 命令存在一些安全风险,因此在实际使用时需要谨慎处理。如果想要避免潜在的安全问题,可以通过其他方式删除文件,比如使用文件系统操作接口或者调用其他程序来完成删除操作。
match
在 awk
中,可以使用 match()
函数和正则表达式来获取文件名。假设给定的路径为 /path/to/file.txt
,可以使用以下代码获取文件名:
echo "/path/to/file.txt" | awk '{match($0, /\/([^\/]+)$/); print substr($0, RSTART+1, RLENGTH-1)}'
上述代码中,首先使用 match()
函数和正则表达式 /\/([^\/]+)$/
匹配字符串末尾的文件名部分。其中,正则表达式中的 \/
匹配反斜杠,[^\/]+
匹配除反斜杠外的任意字符,$
表示匹配字符串末尾。
然后,使用 substr()
函数截取字符串中匹配到的文件名部分,并通过输出命令 print
输出到终端上。这里的 RSTART
和 RLENGTH
变量是 match()
函数内置的用于返回匹配结果的起始位置和长度的变量。
如果是在 awk
脚本中处理文件名,可以将路径作为参数传入脚本中,然后在脚本中使用类似上面的方式获取文件名。例如:
awk '{
match(FILENAME, /\/([^\/]+)$/);
filename = substr(FILENAME, RSTART+1, RLENGTH-1);
# 处理文件名
}' /path/to/file.txt
上述代码中,使用 FILENAME
变量代表当前正在处理的文件名,并通过 match()
函数和 substr()
函数将文件名部分截取出来。接下来,可以在脚本中继续处理该文件名。
function get_name(p) {
match(p, /\\([^\\]+)\.cmd$/, ret);
#return substr(p, RSTART+1, RLENGTH-4)
return ret[1]
}
获取所有类别名称
awk+uniq+sort 统计文件中某字符串出现次数并排序
https://www.cnblogs.com/wangbaihan/p/9262296.html