Question

Trying to use the beauty of Sed so I don't have to manually update a few hundred files. I'll note my employer only allows use of Win8 (joy), so I use Cygwin all day until I can use my Linux boxes at home.

The following works on a Linux (bash) command line, but not Cygwin

> grep -lrZ "/somefile.js" . | xargs -0 -l sed -i -e 's|/somefile.js|/newLib.js|g'
sed: can't read ./testTarget.jsp: No such file or directory

# works
> sed -i 's|/somefile.js|/newLib.js|g' ./testTarget.jsp

So the command by itself works, but not passed through Xargs. And, before you say to use Perl instead of Sed, the Perl equivalent throws the very same error

> grep -lrZ "/somefile.js" . | xargs -0 perl -i -pe 's|/somefile.js|/newLib.js|g'
Can't open ./testTarget.jsp
: No such file or directory.
Was it helpful?

Solution

Use the xargs -n option to split up the arguments and force separate calls to sed.

On windows using GnuWin tools (not Cygwin) I found that I need to split up the input to sed. By default xargs will pass ALL of the files from grep to one call to sed.

Let's say you have 4 files that match your grep call, the sed command will run through xargs like this:

sed -i -e 's|/somefile.js|/newLib.js|g' ./file1 ./file2 ./subdir/file3 ./subdir/file4

If the number of files is too large sed will give you this error. Use the -n option to have xargs call sed repeatedly until it exhausts all of the arguments.

grep -lrZ "/somefile.js" . | xargs -0 -l -n 2 sed -i -e 's|/somefile.js|/newLib.js|g'

In my small example using -n 2 will internally do this:

sed -i -e 's|/somefile.js|/newLib.js|g' ./file1 ./file2 
sed -i -e 's|/somefile.js|/newLib.js|g' ./subdir/file3 ./subdir/file4

I had a large set of files and directories (around 3000 files), and using xargs -n 5 worked great. When I tried -n 10 I got errors. Using xargs --verbose I could see some of the commandline calls were getting cut off at around 500 characters. So you may need to make -n smaller depending on the path length of the files you are woking with.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top