What does lsof|gawk '$4~/txt/{next};/REG.*\(deleted\)$/{printf ">/proc/%s/fd/%d\n", $2,$4}' command mean

I'm reading some articles and I've seen this command:

lsof|gawk '$4~/txt/{next};/REG.*\(deleted\)$/{printf ">/proc/%s/fd/%d\n", $2,$4}'

Could some body help me to understand it


This command will print files from lsof that need truncation.

(It actually does not remove or truncate any files).

lsof will return a list of open files (file descriptors) that is piped into the awk which processes it as follows.

gawk '$4~/txt/{next};/REG.*\(deleted\)$/{printf ">/proc/%s/fd/%d\n", $2,$4}'

The above expression contains two regular expressions separated by a semi colon ;

lets consider the first part gawk '$4~/txt/{next};

Here, if the 4th field contains txt then the next line of text will be read, which the script will start processing from the start again.

The next statement forces awk to immediately stop processing the current record and go on to the next record. This means that no further rules are executed for the current record, and the rest of the current rule's action isn't executed.

Now lets consider the second part of the script /REG.*\(deleted\)$/{printf ">/proc/%s/fd/%d\n", $2,$4}'

Here if the line matches the regular expression /REG.*\(deleted\)$ (the $ means that (deleted) should be the last word on the line), it just prints >/proc/%s/fd/%d\n", $2,$4.

In lsof command $4 is the file descriptor number (for example 53w, the w means the filer has been opened for writing) or filetype, depending on the file. The %d in the printf ensures that only the numbers will be printed, removing any text characters (like the w). $2 prints the process id of process which uses the file so it will print something like >/proc/3989/fd/53 and so on it will print all files that have been deleted but whose file descriptor remains open, in other words, file descriptors that can be truncated safely.


This command will truncate deleted files from lsof.

This first will list open fileslsof

then search for lines recursively one then one{next} that contain REG '$4~/txt/{next};/REG.*\(deleted\)$/ as the fourth parameter then this process relative to this line will be deleted

and then print all results without the lines containing REG and marked as deleted.{printf ">/proc/%s/fd/%d\n", $2,$4}'