Linux CMD
简介
- 常用的linux命令行指令。
- 包括少量实验数据的初步处理(bash脚本)和简单可视化(excel/echart)
find¶
more in blog
{}
is a placeholder that is used to hold results given by the find command.\;
says that for each found result, the [command] is executed
awk¶
awk
是一种强大的文本处理工具,通常用于扫描和处理文本文件中的数据。它非常适合用于格式化和提取数据。以下是一些基本用法和概念:
基本结构¶
awk
的基本结构是:
- pattern: 用于匹配的条件。如果匹配成功,则执行
{ action }
。 - action: 你希望对匹配的行执行的操作。
常见功能¶
-
打印特定列:
这将打印每行的第一和第三列。 -
按条件过滤行:
这将打印第一列大于 50 的所有行。 -
使用分隔符:
这将使用冒号:
作为分隔符,并打印每行的第一列。 -
计算和统计:
这将计算第一列的总和并在最后输出。 -
数组和循环:
这将统计第一列每个值的出现次数。
实用示例¶
打印匹配XXX的前一个元素
grep "xxx" logfile.log | awk '{for(i=1;i<=NF;i++) if ($i ~ /xxx/) print $(i-1)}'
# 打印前第三个元素 和前一个元素,并用TAB连接起来对齐
grep "xxx" logfile.log | awk '{for(i=1;i<=NF;i++) if ($i ~ /xxx/) print $(i-3) "\t" $(i-1)}'
# ...用空格连接起来
grep "xxx" logfile.log | awk '{for(i=1;i<=NF;i++) if ($i ~ /xxx/) print $(i-3), $(i-1)}'
每5行后插入两行空格
awk 'NR%5==0 {print $0 "\n\n"} NR%5!=0 {print}' xxx.log
从结尾数 每5行中间插入两行空格
tac xxx.log | sed 'n;n;n;n;a\\n\n' | tac
- tac 反向读取文件内容
- sed 中的 n 命令表示跳过当前行,移动到下一行,类似于一个 "读取下一行" 的操作。每个 n 都表示跳过一行。n;n;n;n:这个部分表示跳过 4 行,指的是我们只在第 5 行插入内容(每 5 行处理一次)。
- sed 中的 a 命令表示在当前行之后追加内容。
内置变量¶
在 awk
中,NR
和 NF
是非常常用的内置变量,用来处理数据时非常方便。让我们详细解释一下这些变量,以及一些其他常见的内置变量:
常用变量:
-
NR
(Number of Records)NR
表示当前处理的记录的行号。它从1开始,每读入一行数据,NR
就会递增1。- 示例: 输出:
-
NF
(Number of Fields)NF
表示当前行中字段的个数。awk
默认使用空白字符(空格或制表符)来分隔字段。- 示例: 输出:
-
$0
(Whole Line)$0
代表当前行的整个内容。- 示例: 输出:
-
$n
(Field Reference)$n
代表第n
个字段。例如,$1
是第一列,$2
是第二列,依此类推。- 示例: 输出:
-
FNR
(File Number of Record)FNR
表示当前文件中处理的记录(行)号。与NR
不同,FNR
会在每个新文件开始时重新计数。- 示例:
如果
file1
有 3 行,file2
有 2 行,输出会是:
-
FS
(Field Separator)FS
是输入字段的分隔符,默认为空格或制表符。可以通过修改FS
来使用不同的字段分隔符。- 示例: 输出:
-
RS
(Record Separator)RS
是记录(行)的分隔符,默认是换行符("\n"
),但你可以通过修改RS
来定义不同的记录分隔符。- 示例: 输出:
-
OFS
(Output Field Separator)OFS
是输出字段的分隔符,默认为空格。可以通过设置OFS
来定义输出时字段之间的分隔符。- 示例: 输出:
-
ORS
(Output Record Separator)ORS
是输出记录的分隔符,默认为换行符。可以修改ORS
来改变输出记录的分隔符。- 示例: 输出:
-
FILENAME
FILENAME
是当前正在处理的文件名。- 示例:
总结:
NR
:当前记录(行)的行号。NF
:当前行的字段数。$0
:当前行的全部内容。$n
:当前行的第 n 个字段。
这些变量能够让 awk
在处理文本时非常灵活和强大。
sed¶
sed
是一种流编辑器(stream editor),主要用于查找、替换、插入、删除文本中的内容。与 awk
不同,sed
更专注于对文件或文本流的逐行处理,非常适合进行快速的文本替换和编辑任务。
基本结构¶
sed
的基本使用格式如下:
s
: 代表替换(substitute)。pattern
: 要匹配的字符串模式。replacement
: 用来替换匹配模式的字符串。flags
: 替换行为的选项(例如g
代表全局替换,即一行中多次出现的匹配项都替换)。
常见用法¶
-
替换单个匹配项:
这将把old
替换为new
,每行只替换第一个匹配到的old
。 -
全局替换(替换一行中的所有匹配项):
在每行中将所有出现的old
替换为new
。 -
直接修改文件(默认情况下,
sed
不会修改文件,只是打印输出结果):-i
选项会直接修改文件内容。 -
指定替换某一行的匹配项:
只替换第 3 行中的第一个匹配项。 -
删除行:
删除文件中的第 3 行。 -
删除包含某个模式的行:
删除所有包含pattern
的行。 -
打印特定行:
打印文件中的第 3 行。-n
表示禁止默认输出,只打印指定的行。
打印正则匹配的元素
假设你有以下一行数据:
提取/tmp/cpp_{tid}
的部分,即路径 /tmp/cpp_3921738/
。
解释:
grep 'FunctionProfiler'
:先使用grep
提取包含FunctionProfiler
的行。sed -n
:-n
选项表示不自动输出,而是仅在匹配时输出。s/.*\(\/tmp\/cpp_[0-9]\+\/\).*/\1/
:使用sed
替换命令来捕获匹配的部分。.*
:匹配任意前导字符。\(\/tmp\/cpp_[0-9]\+\/\)
:这是我们要提取的部分,匹配/tmp/cpp_
后跟一个或多个数字,使用\1
引用。.*
:匹配剩余的字符。p
:表示打印匹配的结果。
这个命令会输出路径 /tmp/cpp_3921738/
。
- 查找并替换带有特殊字符的字符串:
当要替换的字符串中含有特殊字符(如
/
),可以使用其他字符作为分隔符。例如: 在这个例子中,|
被用作分隔符,避免了/
字符冲突。
实用示例¶
-
在某行之后插入内容:
在第 3 行后插入"This is the inserted line."
。 -
在某行之前插入内容:
在第 3 行前插入"This is the inserted line."
。 -
替换特定范围内的行:
仅替换第 3 行到第 5 行中的old
。 -
替换文件中的多个字符串:
使用-e
选项可以执行多个替换操作。 -
删除文件中的空行:
删除所有空行。
总结¶
- 文本替换是
sed
的核心功能,主要用于批量替换和删除。 sed
的语法简单、易用,并且非常适合处理大文件或者进行批量文件处理。- 与
awk
不同,sed
更偏向行操作,对于简单的查找、替换任务非常高效。
cut¶
提取git id
echo¶
连续数据 + 可视化¶
使用 grep
和 sed
来提取数字并将它们格式化为一行,以逗号分隔。下面是一个示例命令:
grep -a 'avg syn forward cost' llama_bindCore_env1.log | sed 's/.*: \([0-9.]*\) ms/\1/' | paste -sd ','
grep -a 'avg syn forward cost' llama_bindCore_env1.log
:提取包含指定字符串的行。sed 's/.*: \([0-9.]*\) ms/\1/'
:使用sed
将每行转换为仅包含数字。这里,.*:
表示匹配行中前面的所有内容,\([0-9.]*\)
捕获数字(包括小数点),ms
后面的部分会被删除。paste -sd ','
:将所有输出合并为一行,并用逗号分隔。
运行这个命令后,你将得到一个逗号分隔的数字列表。
列表化后,无论是用excel还是echart都能很方便的可视化
x轴连续数字生成
使用 seq
命令结合 -s
选项将数字生成到同一行,并使用逗号分隔:
seq -s, 1 100
:生成从 1 到 100 的连续数字,逗号分隔。tr -d '\n'
:删除所有换行符,使输出在同一行。> output.txt
:将结果输出到output.txt
文件中。
正态分布图¶
实验时,要先确定最小可重复测试单元
比如测量OpenSora的性能时,就是其每个可重复的step。
运行histogram.sh input.txt > echart.data
, 输入数据是一行一个数据。
脚本如下:
min=50 # 数据的最小值
max=60 # 数据的最大值
bins=100 # 分成100个区间
awk -v min=$min -v max=$max -v bins=$bins '{
bin_width = (max - min) / bins;
bin = int(($1 - min) / bin_width);
if (bin >= 0 && bin < bins) {
freq[bin]++;
}
}
END {
for (i = 0; i < bins; i++) {
if (i > 0) {
printf ",";
}
printf "%d", (freq[i] ? freq[i] : 0);
}
printf "\n";
}' $1
参考文献¶
上面回答部分来自ChatGPT-4omini,没有进行正确性的交叉校验。