9

I don't have to move the folders, only the files.

I have tried mv * but this command moves the folders also.

12

If you want to move everything except directories from $SOURCE_DIR to $TARGET_DIR, you can use this command:

find "$SOURCE_DIR" -maxdepth 1 -not -type d -exec mv -t "$TARGET_DIR" -- '{}' +

Explained in detail:

  • find: The find search for files in a directory
  • $SOURCE_DIR: The directory to search in
  • -maxdepth 1: Do not look inside subdirectories
  • -not -type d: Ignore directories
    • You could also use -type f if you only want to copy things that are strictly files, but I prefer the above because it also catches everything that's neither a file nor a directory (in particular symbolic links)
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Run the command mv -t "$TARGET_DIR" -- FILES... where FILES... are all the matching files (thanks @DavidFoerster)
  • 2
    find ... -exec mv -t "$TARGET_DIR" -- '{}' + would be safer (in case $TARGET_DIR is no directory or the match starts with -) and more efficient (because it doesn't spawn a new sub-process for every matched file). – David Foerster Apr 1 '17 at 12:50
  • @DavidFoerster Thanks, updated (also learnt something new today!) – Frxstrem Apr 1 '17 at 13:36
5

I think you want to mv only your files.First go to the your directory and use this command, replace $TARGET with your target directory path. If you want to copy your files replace mv with cp.

find . -type f -exec mv {} $TARGET \;

if I explain this, find . -type f means select all files and -exec mv {} $TARGET \; means execute mv command to all selected items.


Previous answer has a error.. it mv all files inside sub directories also. The quick fix is use -maxdepth 1. Then it not recursively mv files within sub directories. Below is the correct one..

find . -maxdepth 1 -type f -exec mv {} $TARGET \;
  • I don't think the questioner wants this! It would also move all files in any subdirectories into that same target directory. The -type f doesn't prevent recursion. – Martin Thornton Apr 1 '17 at 11:30
  • @MartinThornton thank you for your suggestion.. i will edit my answer... – Emalsha Rasad Apr 1 '17 at 11:44
3

Python approach

When dealing with files recursively, find is the way to go. In this particular case it's not necessary, but can be used with -maxdepth 1 as other answers show.

Simple python command can do it as well. Here's an example:

$ tree
.
├── a_directory
└── a_file

$ python -c "import os,shutil;fl=[f for f in os.listdir('.') if os.path.isfile(f)];                                      
> map(lambda x:shutil.move(x,'./a_directory'),fl)"

$ tree
.
└── a_directory
    └── a_file

1 directory, 1 file

How this works:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)] iterates over all items that os.listdir('.') finds and we test whether the item is a file using os.path.isfile() function.

  • Once fl file list is built, we use map() function. This function takes two arguments - a function, and a list of items; it will perform the function that we gave it per each file in a list. Thus here we havelambda x:shutil.move(x,'./a_directory') as anonymous function which will move a a given file to a given directory, and then we have the fl - the list of files that we built up.

For readability and general usage, we could also rewrite this as a general python script, which takes two arguments - source directory and destination subdirectory.

#!/usr/bin/env python3
from os import listdir
from os.path import isfile,realpath
from os.path import join as joinpath
from shutil import move
from sys import argv

# this is script's full path
script=realpath(__file__)
# get all items in a given directory as list of full paths
fl=[ joinpath(argv[1],f) for f in listdir(argv[1]) ] 
# filter out script itself ( just in case) and directories
fl_filtered = [ f for f in fl if isfile(f) and not script == realpath(f) ]
# Uncomment this in case you want to see the list of files to be moved
# print(fl_filtered)
# move the list of files to the given destination
for i in fl_filtered:
     move(i,argv[2])

And the usage is like so:

$ tree
.
├── a_directory
├── a_file
└── files2subdir.py

1 directory, 2 files

# Notice: the script produces no output unless you uncomment print statement
$ ./files2subdir.py "." "./a_directory"                                                                                  

$ tree
.
├── a_directory
│   └── a_file
└── files2subdir.py
3

If you're using zsh instead of bash, you can do this:

mv "$SOURCE"/*(.) "$TARGET"

The (.) at the end is called a glob qualifier; the . inside specifically means to only match regular files.

Doing a mv *(.) "$target" is quick and practical. However, if you're doing this as part of a script, you might want to consider instead writing something like what Frxstrem and David Forester suggested, mv -t "$target" -- *(.), to better handle corner cases that might arise in other people's usage.

  • 1
    As David Forester pointed out on my answer, mv -t "$TARGET" -- "$SOURCE"/*(.) would be safer (in case "$TARGET" starts with a - or is not a directory). I do like the zsh solution though! – Frxstrem Apr 1 '17 at 22:19
2

To move everything except directories from source-dir directory to destination-dir directory, in Python:

#!/usr/bin/env python3
"""Usage: mv-files <source-dir> <destination-dir>"""
import shutil
import sys
from pathlib import Path

if len(sys.argv) != 3:
    sys.exit(__doc__)  # print usage & exit 1
src_dir, dest_dir = map(Path, sys.argv[1:])
for path in src_dir.iterdir():
    if not path.is_dir():
        shutil.move(str(path), str(dest_dir / path.name))

See Running Python File in Terminal.

  • @SergiyKolodyazhnyy I don't see such requirement in pep-8 and (according to the example there) it is actually the exact opposite: import mypackage before from mypackage import ... – jfs Apr 2 '17 at 22:41
  • @SergiyKolodyazhnyy don't confuse the special from __future__ imports and ordinary from pathlib imports. – jfs Apr 3 '17 at 4:30
  • Yeah, looks like I've misread that part. No, you're right, import module should be first (which is library and third party imports) from module import object should be last ( local/library specific) – Sergiy Kolodyazhnyy Apr 3 '17 at 4:53
0

I'd use

mv *.*

this will work as long as your folders don't have extensions.

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.