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

2番目の列(プロセスのpid)のみを抽出するにはどうすればよいですか?

9番目の列(ファイルパス名)のみを抽出する方法は? (パス名には、Linuxおよびext4ファイルシステムで許可されているすべての文字を含めることができます。)

私の本当の命令は

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

wineserv最初の列「COMMAND」ではなく、5番目の列「TYPE」がありREG、9番目の列「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つのフィールドを削除して残りを印刷します。

関連情報