deostroll deostroll - 25 days ago 7
Linux Question

removing empty lines from a pipe using sed

$ find ~/AppData/Local/atom/ -name atom.sh -type f | grep -FzZ 'cli/atom.sh' | sed '/^\s*$/d' | cat -n
1 /c/Users/devuser/AppData/Local/atom/app-1.12.1/resources/cli/atom.sh
2 /c/Users/devuser/AppData/Local/atom/app-1.12.2/resources/cli/atom.sh
3


I tried a number of sed/awk-based options to get rid of the blank line. (
#3
in the output). But I can't quite get it right...

I need to get the last line into a variable...

The below actual command I am working with fails to give an output...

find ~/AppData/Local/atom/ -name atom.sh -type f | grep -FzZ 'cli/atom.sh' | sed '/^$/d' | tail -n 1

Answer

The problem is the -Z flag of grep. It causes grep to terminate matched lines with a null character instead of a newline. This won't work well with sed, because sed processes input line by line, and it expects each line to be terminated by a newline. In your example grep doesn't emit any newline characters, so as far as sed is concerned, it receives a block of text without a terminating newline, so it processes it as a single line, and so the pattern /^\s*$/ doesn't match anything.

Furthermore, the -z flag would only make sense if the filenames in the output of find were terminated by null characters, that is with the -print0 flag. But you're not using that, so the -z flag in grep is pointless. And the -Z flag is pointless too, because that should be used when the next command in the pipeline expects null-terminated records, which is not your case.

Do like this:

find ~/AppData/Local/atom/ -name atom.sh -type f -print0 | grep -zF 'cli/atom.sh' | tr '\0' '\n' | tail -n 1