跳转至

Linux CMD

简介

  • 常用的linux命令行指令。
  • 包括少量实验数据的初步处理(bash脚本)和简单可视化(excel/echart)

find

more in blog

find . -type f -size +10M -exec rm -rf {} \;
  1. {} is a placeholder that is used to hold results given by the find command.
  2. \; says that for each found result, the [command] is executed

awk

awk 是一种强大的文本处理工具,通常用于扫描和处理文本文件中的数据。它非常适合用于格式化和提取数据。以下是一些基本用法和概念:

基本结构

awk 的基本结构是:

awk 'pattern { action }' file
  • pattern: 用于匹配的条件。如果匹配成功,则执行 { action }
  • action: 你希望对匹配的行执行的操作。

常见功能

  1. 打印特定列

    awk '{print $1, $3}' file.txt
    
    这将打印每行的第一和第三列。

  2. 按条件过滤行

    awk '$1 > 50' file.txt
    
    这将打印第一列大于 50 的所有行。

  3. 使用分隔符

    awk -F ':' '{print $1}' /etc/passwd
    
    这将使用冒号 : 作为分隔符,并打印每行的第一列。

  4. 计算和统计

    awk '{sum += $1} END {print sum}' file.txt
    
    这将计算第一列的总和并在最后输出。

  5. 数组和循环

    awk '{count[$1]++} END {for (i in count) print i, count[i]}' file.txt
    
    这将统计第一列每个值的出现次数。

实用示例

计算平均值

awk '{sum += $1; count++} END {print sum / count}' file.txt
计算文件中第一列的平均值。

打印匹配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 命令表示在当前行之后追加内容。

类似sed 替换文本

awk '{gsub(/old/, "new"); print}' file.txt
将每行中的 old 替换为 new

内置变量

awk 中,NRNF 是非常常用的内置变量,用来处理数据时非常方便。让我们详细解释一下这些变量,以及一些其他常见的内置变量:

常用变量:
  1. NR (Number of Records)

    • NR 表示当前处理的记录的行号。它从1开始,每读入一行数据,NR 就会递增1。
    • 示例:
      echo -e "a\nb\nc" | awk '{print NR, $0}'
      
      输出:
      1 a
      2 b
      3 c
      
  2. NF (Number of Fields)

    • NF 表示当前行中字段的个数awk 默认使用空白字符(空格或制表符)来分隔字段。
    • 示例:
      echo "a b c" | awk '{print NF}'
      
      输出:
      3
      
  3. $0 (Whole Line)

    • $0 代表当前行的整个内容
    • 示例:
      echo "a b c" | awk '{print $0}'
      
      输出:
      a b c
      
  4. $n (Field Reference)

    • $n 代表第 n 个字段。例如,$1 是第一列,$2 是第二列,依此类推。
    • 示例:
      echo "a b c" | awk '{print $1, $2}'
      
      输出:
      a b
      
  5. FNR (File Number of Record)

    • FNR 表示当前文件中处理的记录(行)号。与 NR 不同,FNR 会在每个新文件开始时重新计数。
    • 示例:
      awk '{print FNR, $0}' file1 file2
      
      如果 file1 有 3 行,file2 有 2 行,输出会是:
      1 <file1 第一行内容>
      2 <file1 第二行内容>
      3 <file1 第三行内容>
      1 <file2 第一行内容>
      2 <file2 第二行内容>
      
  6. FS (Field Separator)

    • FS 是输入字段的分隔符,默认为空格或制表符。可以通过修改 FS 来使用不同的字段分隔符。
    • 示例:
      echo "a,b,c" | awk 'BEGIN {FS=","} {print $1, $2}'
      
      输出:
      a b
      
  7. RS (Record Separator)

    • RS 是记录(行)的分隔符,默认是换行符("\n"),但你可以通过修改 RS 来定义不同的记录分隔符。
    • 示例:
      echo -e "a\nb\nc" | awk 'BEGIN {RS="b"} {print $0}'
      
      输出:
      a
      c
      
  8. OFS (Output Field Separator)

    • OFS 是输出字段的分隔符,默认为空格。可以通过设置 OFS 来定义输出时字段之间的分隔符。
    • 示例:
      echo "a b c" | awk 'BEGIN {OFS=","} {print $1, $2, $3}'
      
      输出:
      a,b,c
      
  9. ORS (Output Record Separator)

    • ORS 是输出记录的分隔符,默认为换行符。可以修改 ORS 来改变输出记录的分隔符。
    • 示例:
      echo -e "a\nb\nc" | awk 'BEGIN {ORS=";"} {print $0}'
      
      输出:
      a;b;c;
      
  10. FILENAME

    • FILENAME 是当前正在处理的文件名。
    • 示例:
      awk '{print FILENAME, $0}' file1 file2
      

总结:

  • NR:当前记录(行)的行号。
  • NF:当前行的字段数。
  • $0:当前行的全部内容。
  • $n:当前行的第 n 个字段。

这些变量能够让 awk 在处理文本时非常灵活和强大。

sed

sed 是一种流编辑器(stream editor),主要用于查找、替换、插入、删除文本中的内容。与 awk 不同,sed 更专注于对文件或文本流的逐行处理,非常适合进行快速的文本替换和编辑任务。

基本结构

sed 的基本使用格式如下:

sed 's/pattern/replacement/flags' file
  • s: 代表替换(substitute)。
  • pattern: 要匹配的字符串模式。
  • replacement: 用来替换匹配模式的字符串。
  • flags: 替换行为的选项(例如 g 代表全局替换,即一行中多次出现的匹配项都替换)。

常见用法

  1. 替换单个匹配项

    sed 's/old/new/' file.txt
    
    这将把 old 替换为 new每行只替换第一个匹配到的 old

  2. 全局替换(替换一行中的所有匹配项)

    sed 's/old/new/g' file.txt
    
    在每行中将所有出现的 old 替换为 new

  3. 直接修改文件(默认情况下,sed 不会修改文件,只是打印输出结果):

    sed -i 's/old/new/g' file.txt
    
    -i 选项会直接修改文件内容。

  4. 指定替换某一行的匹配项

    sed '3s/old/new/' file.txt
    
    只替换第 3 行中的第一个匹配项。

  5. 删除行

    sed '3d' file.txt
    
    删除文件中的第 3 行。

  6. 删除包含某个模式的行

    sed '/pattern/d' file.txt
    
    删除所有包含 pattern 的行。

  7. 打印特定行

    sed -n '3p' file.txt
    
    打印文件中的第 3 行。-n 表示禁止默认输出,只打印指定的行。

打印正则匹配的元素

假设你有以下一行数据:

FunctionProfiler: Profiling completed, data saved to /tmp/cpp_3921738/3921738_output.txt
提取 /tmp/cpp_{tid} 的部分,即路径 /tmp/cpp_3921738/

grep 'FunctionProfiler' your_file | sed -n 's/.*\(\/tmp\/cpp_[0-9]\+\/\).*/\1/p'

解释:

  • 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/

  1. 查找并替换带有特殊字符的字符串: 当要替换的字符串中含有特殊字符(如 /),可以使用其他字符作为分隔符。例如:
    sed 's|/old/path|/new/path|g' file.txt
    
    在这个例子中,| 被用作分隔符,避免了 / 字符冲突。

实用示例

  1. 在某行之后插入内容

    sed '3a This is the inserted line.' file.txt
    
    在第 3 行后插入 "This is the inserted line."

  2. 在某行之前插入内容

    sed '3i This is the inserted line.' file.txt
    
    在第 3 行前插入 "This is the inserted line."

  3. 替换特定范围内的行

    sed '3,5s/old/new/g' file.txt
    
    仅替换第 3 行到第 5 行中的 old

  4. 替换文件中的多个字符串

    sed -e 's/old1/new1/g' -e 's/old2/new2/g' file.txt
    
    使用 -e 选项可以执行多个替换操作。

  5. 删除文件中的空行

    sed '/^$/d' file.txt
    
    删除所有空行。

总结

  • 文本替换sed 的核心功能,主要用于批量替换和删除
  • sed 的语法简单、易用,并且非常适合处理大文件或者进行批量文件处理。
  • awk 不同,sed 更偏向行操作,对于简单的查找、替换任务非常高效。

cut

提取git id

(cd /root/document/shaojie/github/pytorch; git log | head -n 1 | awk '{print $2}' | cut -c 1-5)

echo

连续数据 + 可视化

使用 grepsed 来提取数字并将它们格式化为一行,以逗号分隔。下面是一个示例命令:

grep -a 'avg syn forward cost' llama_bindCore_env1.log | sed 's/.*: \([0-9.]*\) ms/\1/' | paste -sd ','
  1. grep -a 'avg syn forward cost' llama_bindCore_env1.log:提取包含指定字符串的行。
  2. sed 's/.*: \([0-9.]*\) ms/\1/':使用 sed 将每行转换为仅包含数字。这里,.*: 表示匹配行中前面的所有内容,\([0-9.]*\) 捕获数字(包括小数点),ms 后面的部分会被删除。
  3. paste -sd ',':将所有输出合并为一行,并用逗号分隔。

运行这个命令后,你将得到一个逗号分隔的数字列表。

列表化后,无论是用excel还是echart都能很方便的可视化

x轴连续数字生成

使用 seq 命令结合 -s 选项将数字生成到同一行,并使用逗号分隔:

seq -s, 1 n | tr -d '\n' > output.txt
  • 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,没有进行正确性的交叉校验。