7

I have a folder A which has files and directories, I want to move all those files and directories to another folder B, except file, file2, directory, and directory2.

How can this be done?

9

With zsh:

setopt extendedglob # best in ~/.zshrc
mv A/^(file|directory)(|2)(D) B/

(the (D) to include dot (hidden) files).

With bash:

shopt -s extglob dotglob failglob
mv A/!(@(file|directory)?(2)) B/

With ksh93

(FIGNORE='@(.|..|@(file|directory)?(2))'; mv A/* B)
  • I don't even want to think about how much time you must have spent in each shell to learn this! Great answer! – jpaugh Oct 11 '16 at 14:51
10

what i usually do

cd A
ls > a

(assuming you have no 'a' file).

vi a

remove whatever file or directory to be kept in place.

mv $(<a) B
  • Thanks for the answer, I'm thinking some of the experts maybe have some command/"one liner" which is less of a hassle. – somethingSomething Sep 9 '14 at 9:30
  • 1
    It depends, if I have to do it once (my solution) or many time @Falko's solution. – Archemar Sep 9 '14 at 9:35
  • 2
    @somethingSomething This solution allows you to check what you are about to do before you do it. Don't underestimate that. – Ben Sep 9 '14 at 12:54
  • 1
    @Ben, beware though that you have to check that the file names don't contain blank or wildcards or don't start with -. You won't be able to spot file names that contain newline characters and it will omit hidden files. – Stéphane Chazelas Sep 9 '14 at 16:03
  • 2
    This can be dangerous for one more reason: if ls is an alias to ls -F (which is common when not using colors), source paths can have leading /, which can have severe side effects - see "Warning" and "Trailing slashes" in info mv (or pinfo mv, but not in man mv) – Volker Siegel Sep 10 '14 at 2:46
5

You can use find with excluded expressions:

find . ! -name . -prune ! -path ./file \
                        ! -path ./file2 \
                        ! -path ./directory \
                        ! -path ./directory2 \
     -exec mv {} your_destination \;

This solution is inspired by this question.

  • I get: find: unknown predicate `-E' if I copy and paste your solution, and modify "your_destination" accordingly. – somethingSomething Sep 9 '14 at 9:50
  • 1
    @somethingSomething: I guess you can drop the -E option. But there might be differences between our systems, since I'm currently on OSX. – Falko Sep 9 '14 at 9:57
2
ls | egrep -v '(file|file2|directory|directory2)' | xargs -i mv {} ../B/
1

If ./A and ./B are on the same filesystem and if these files do not already exist in ./B:

file file2 directory directory2

...then this operation should just be atomic:

cd ./A; mv * ../B
for mv in file file2 directory directory2
do mv ../B/"$mv" .
done

If they are not, then there are at least 8 additional cross-device copies done with the above set of commands.

  • Not aware of any shell which guarantees this to truly be atomic. However it should be "really really fast" if its on the same fs. EDIT - that is each mv may be atomic if on the same fs but the entire mv is not atomic – Brandin Sep 9 '14 at 15:26
  • @Brandin - the shell has no involvement in whether or not that is an atomic operation or not. mv unlinks and renames when not crossing devs - it just affects dentries, basically, as i understand it. But the shell doesnt get into that. – mikeserv Sep 9 '14 at 15:40
0

$ sudo mv (source folder name) A B(destination foldername)

ex: create empty dir some sub folder a 1)sudo mkdir -p A/{b/{a,b,c},c,d}

2)ls A/

b c d

3) sudo mkdir B

5)sudo mv a(folder) b(folder)

0

You could use a bash array to store which ones you want to skip and then use the containsElement function demonstrated here:

$ skiplist=(file file2 directory directory2)
$ for f in *; do if containsElement "$f" "${skiplist[@]}"; then continue; fi;
mv -v "$f" B; done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.