3

I need help piping some sed output to xargs. This is not working, nothing is being echoed:

fswatch -xr mysitedir | sed -n '/Updated$/p' | xargs -L1 -I {} echo {}

My end goal here is not actually to echo, but to trigger my build tool (soupault) whenever fswatch detects changes in my site directory. The sed command is basically interchangeable with grep in my case. It simply filters this stream of events:

$ fswatch -xr site
/home/jplew/Sites/projects/soupault/site IsDir
/home/jplew/Sites/projects/soupault/site PlatformSpecific
/home/jplew/Sites/projects/soupault/site IsDir
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated
/home/jplew/Sites/projects/soupault/site/blog PlatformSpecific
/home/jplew/Sites/projects/soupault/site/blog IsDir
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated
/home/jplew/Sites/projects/soupault/site/blog PlatformSpecific
/home/jplew/Sites/projects/soupault/site IsDir
/home/jplew/Sites/projects/soupault/site PlatformSpecific
/home/jplew/Sites/projects/soupault/site IsDir
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated

Down to this:

$ fswatch -xr site | sed -n '/Updated$/p' 
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated
/home/jplew/Sites/projects/soupault/site/blog/index.html Updated

Why isn't xargs printing anything?

2
  • 1
    You don't actually need to use sed here. fswatch can filter events by itself. There's even an example very similar to what you want in the man page: fswatch --event Updated path/to/directory | xargs -n 1 bash_command. Just add -0 --event Updated to your fswatch command and -0 -r to xargs, and you should be good to go. Commented Apr 19, 2021 at 12:56
  • oh wow, I completely missed that option, thanks so much. Not the answer to my question but the solution to my problem. :) Commented Apr 19, 2021 at 13:31

1 Answer 1

4

I found the answer here: https://stackoverflow.com/a/23030127/1011766

Because fswatch is a long-running process, I had to use sed's -u flag to unbuffer the stream.

-u, --unbuffered

       load minimal amounts of data from the input files and flush the output buffers more often

This simple fix did it:

fswatch -xr mysitedir | sed -un '/Updated$/p' | xargs -L1 -I {} echo {}


NOTE

Better solution from @cas for my specific use-case is to use fswatch's built-in --event flag:

fswatch --event Updated -0r mysitedir | xargs -0r -I{} echo {}
3
  • 1
    Or grep --line-buffered 'Updated$' but you shouldn't use xargs -I without -d/-0 (unless fswatch happens to write data in that very specific format which seems unlikely) nor echo here (and -L1 is redundant). You'd also want to consider what would happen if a watched filename contains newline characters. Commented Apr 19, 2021 at 11:45
  • thanks for the tips! fswatch has a -0 flag which plays nice with xargs -0, but can you suggest how to get the sed command in between to recognize and pipe through the null character? This does not produce any output: fswatch -0xr site templates soupault.conf | sed -n "/Updated\x0/p" Commented Apr 19, 2021 at 12:20
  • 2
    @JPLew if it's GNU sed, it has a -z or --null-data option Commented Apr 19, 2021 at 12:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.