3
ls -al | grep -v '^d' | xargs mv -t mysubdir

I use the above command extensively on Red Hat systems.

It moves all files in the current directory to mysubdir

$ mv --version
Usage: mv [-f] [-i] [-e warn|force|ignore] f1 f2
       mv [-f] [-i] [-e warn|force|ignore] f1 ... fn d1
       mv [-f] [-i] [-e warn|force|ignore] d1 d2

what is the above command's equivalent in HP-UX (HP-UX 11i Version 3 Feb 2007)

2 Answers2

1

If xargs on your HP-UX 11i has the -I flag you can do this, although I'm not entirely sure how you have managed to use ls -l output with the mv:

ls -al | grep -v '^d' | xargs -I {} mv {} mysubdir

Failing that you could do this, which I think would be my preferred solution:

ls -a | while read ITEM; do test ! -d "$ITEM" && mv "$ITEM" mysubdir; done

Either can be encompassed with a shell function or script, so the length of the one-liner isn't necessarily relevant.

Chris Davies
  • 116,213
  • 16
  • 160
  • 287
1

mv -t is a convenience provided by the GNU mv command (the one you have on Linux). Other unix variants don't have that, you need to put the destination at the end. This does make it less convenient to use with xargs or find … -exec (which is why mv -t was invented).

One way to put the arguments in the right order is to invoke a shell.

… | xargs sh -c 'mv "$@" "$0"' mysubdir

(mysubdir is argument 0 to the shell; the arguments passed in batches by xargs make up the positional parameters "$@".)

Beware that xargs is not robust: it expects inputs in a peculiar quotes syntax. Your snippet breaks if you have file names containing whitespace or one of the characters \"'. See Why does my shell script choke on whitespace or other special characters? for more information. To avoid problems with special characters in file names, use find … -exec …:

find . -name . -o -type d -prune -o sh -c 'mv "$@" "$0"' mysubdir {} +

(-name . -o -type d -prune -o skips subdirectories without recursing into them.)

For your use case of moving non-directories, if mysubdir itself doesn't already contain subdirectories, it would be simpler to move all files, then move directories back:

mv * mysubdir/; mv mysubdir/*/ .

Alternatively, since you don't want to recurse into subdirectories, you could use a shell loop to enumerate files, and skip the ones that are directories.

for x in ./*; do
  [ -d "$x" ] || mv "$x" mysubdir/
done