如何在 lsof 输出中仅提取 pid 列和路径名列?

如何在 lsof 输出中仅提取 pid 列和路径名列?
$ sudo lsof -u t  |   grep -i "\.pdf" 

evince  1788    t   37r      REG                8,4    176328     134478 /home/t/some/path1/white space/string1 + string2 string3.pdf
evince  3737    t   36r      REG                8,4   1252636    6692680 /home/t/some/path2/white space/string5 string3.pdf

如何仅提取第二列(进程的 pid)?

如何仅提取第九列(文件路径名)? (路径名可以包含 Linux 和 ext4 文件系统允许的任何字符)

我真正的命令是

$ sudo lsof -u t  | grep -v "wineserv" | grep REG  |   grep "\.pdf" | grep  "string"

我将在其中搜索第一列“COMMAND”不是wineserv、第五列“TYPE”是REG、第九列“NAME”包含.pdf和 的记录string

更喜欢 bash、awk 或 Python 解决方案(也许还有 Perl,但我不懂 Perl,所以无法验证它是否正确或稍后修改)

谢谢。

答案1

使用正则表达式:

$ ... | perl -nlE '/.*? (\d+).*?(\/.*)/ and print("$1 ; $2")' 

1788 ; /home/t/some/path1/white space/string1 + string2 string3.pdf
3737 ; /home/t/some/path2/white space/string5 string3.pdf

答案2

如果我理解你的要求,这应该可行:

awk '{ for (i=9; i<=NF; i++) {
    if ($i ~ "string" && $1 != "wineserv" && $5 == "REG" && $NF ~ "\.pdf$") {
        $1=$2=$3=$4=$5=$6=$7=$8=""
        print
    }
}}'
  • 循环遍历从 9 到末尾的所有字段,如果其中包含string

    • 检查字段 1 是否不等于wineserv
    • 字段 5 等于REG
    • 最后一个字段包含.pdf(我认为可以安全地假设即使文件有空格,扩展名也应该在最后一部分)
  • 如果满足所有条件,则删除前 8 个字段并打印剩下的内容

相关内容