• Not sure about this...

    If there's less than 10% free on the disk is there even space for a new 13GB datafile?

    No business disruption is specified, but then the solution is to copy out entire tables into others?

    This will result in a table lock (significantly more contention than the shrink command) and possibly missing/incorrect data unless the table is quiescent between being loaded & renamed. You will also need to handle any foreign key constraints referencing the table. And deal with a load of plan recompilations after the rename.

    running shrinkfile without moving tables can result in long running shrink statement which holds locks

    As opposed to long running insert statements which holds locks? Shrinkfile is designed to run transparently, with the possible exception of an emptyfile operation.

    This would have run for hours and caused serious production contention if the tables and indexes were moved to a new filegroup

    But that's exactly what you have done?

    I do agree with using shrinkfile over shrinkdatabase and leaving suitable room for growth in your target file size though.