![如何在 lsof 输出中仅提取 pid 列和路径名列?](https://linux22.com/image/148299/%E5%A6%82%E4%BD%95%E5%9C%A8%20lsof%20%E8%BE%93%E5%87%BA%E4%B8%AD%E4%BB%85%E6%8F%90%E5%8F%96%20pid%20%E5%88%97%E5%92%8C%E8%B7%AF%E5%BE%84%E5%90%8D%E5%88%97%EF%BC%9F.png)
$ 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
(我认为可以安全地假设即使文件有空格,扩展名也应该在最后一部分)
- 检查字段 1 是否不等于
如果满足所有条件,则删除前 8 个字段并打印剩下的内容