如何用BASH脚本提取文件指定列并保留PKCS11提示行
解决BASH脚本提取特定列的问题
针对你提到的两个需求,我用awk工具来实现,它是处理文本列的绝佳选择,下面分情况给出具体方案:
1. 处理现有脚本输出:保留指定列和提示行
假设你的现有脚本输出已经保存到input.txt(或者直接从管道读取),我们可以用awk精准筛选需要的内容,完美匹配你给出的示例输入输出:
实现命令
awk ' # 保留开头的PKCS11提示行 /^PKCS11 provider/ { print; next } # 输出自定义的目标表头 /^| COUNT / { print "| COUNT | CKA CLASS | CKA LABEL |"; next } # 输出对应长度的分隔线 /^\+-------+/ { print "+-------+-----------------+------------------------------------------------------------------+"; next } # 提取数据行的第2、4、6个字段(以|为分隔符)并格式化输出 /^| [0-9]+ / { printf "| %s | %s | %s |\n", $2, $4, $6 } ' input.txt > output.txt
命令解释
- 提示行处理:匹配以
PKCS11 provider开头的行,直接打印,next跳过后续逻辑避免重复处理。 - 表头处理:匹配原表头行,直接输出我们需要的精简表头,确保格式和目标一致。
- 分隔线处理:匹配原分隔线行,输出对应长度的分隔线,和目标输出的分隔线完全对齐。
- 数据行处理:匹配以
| 数字开头的数据行,提取以|分割后的第2(COUNT)、4(CKA CLASS)、6(CKA LABEL)个字段,用printf格式化输出成目标格式。
如果要整合到现有脚本调用流程里,可以这样写:
# 调用目标脚本并将输出暂存到临时文件 ./your_existing_script.sh > temp_output.txt # 用awk处理得到最终结果 awk ' /^PKCS11 provider/ { print; next } /^| COUNT / { print "| COUNT | CKA CLASS | CKA LABEL |"; next } /^\+-------+/ { print "+-------+-----------------+------------------------------------------------------------------+"; next } /^| [0-9]+ / { printf "| %s | %s | %s |\n", $2, $4, $6 } ' temp_output.txt > final_output.txt # 可选:清理临时文件 rm temp_output.txt
2. 通用提取特定列的BASH脚本
如果你需要一个通用的工具脚本,能从任意文本文件提取指定列,这里有一个可复用的脚本:
脚本代码(保存为extract_columns.sh)
#!/bin/bash # 参数检查:确保传入输入文件和至少一个列号 if [ $# -lt 2 ]; then echo "用法: $0 <输入文件路径> <列号1> <列号2> ..." exit 1 fi input_file="$1" shift # 移除第一个参数,剩下的都是列号 column_numbers="$@" # 使用awk提取指定列,默认以空格为分隔符;如果是|分隔,可添加-F"|"参数 awk -v cols="$column_numbers" ' BEGIN { split(cols, col_array) # 将列号字符串拆分为数组 } { # 遍历列号数组,依次输出对应列的内容 for (i=1; i<=length(col_array); i++) { printf "%s", $(col_array[i]) if (i < length(col_array)) printf "\t" # 列之间用制表符分隔,可改为空格或| } printf "\n" } ' "$input_file"
使用示例
比如针对你的示例输入文件,提取第2、4、6列(对应COUNT、CKA CLASS、CKA LABEL),需要指定分隔符为|:
chmod +x extract_columns.sh ./extract_columns.sh input.txt -F"|" 2 4 6
这样就能得到你需要的列内容,你可以根据实际需求调整分隔符和列号。
内容的提问来源于stack exchange,提问作者Harinder
相关产品推荐
相关产品推荐

