We can copy some file by extensions like this:
cp *.txt ../new/ but how can I copy all files that have no extension?
The answer from @ubaid-ashraf is almost there. The way to specify file with no extension, in ksh would be:
cp -- !(*.*) /new/path/ so that any file with dot in file name is skipped.
For that to work in bash, you need to enable the extglob option (shopt -s extglob) and the kshglob option in zsh (set -o kshglob).
cp would skip directories unless used with -r or -R option. my.file.txt? -- after cp? i do that without -- and it works. btw, what is usage of --? You can do something like:
cp -- !(*.txt) /path/to/directory The above code will copy all the files without .txt extension. You can also give multiple extension via pipe character.
For example:
cp -- !(*.txt|*.c|*.py) /path/to/directory You can use find to get only files (regular ones only with -type f) that have no extension:
LC_ALL=C find . -maxdepth 1 ! -name '*.*' -type f So your copy command would be:
LC_ALL=C find . -maxdepth 1 ! -name '*.*' -type f -exec cp {} destination_folder/ \; Note that find (contrary to shell globs) does consider hidden files, but since those contain a . (at least one at the start), they won't be copied. For instance, neither .bashrc nor .file.conf will be copied as they both contain a . even if in the first case, the dot may not be seen as the extension delimiter. Changing the pattern to ?*.* would cause .bashrc to be copied and not .file.conf.
To avoid running one cp per file, on GNU systems:
LC_ALL=C find . -maxdepth 1 ! -name '*.*' -type f -exec cp -t destination_folder {} + On BSDs:
LC_ALL=C find . -maxdepth 1 -type f \! -name '*.*' -print0 | xargs -r0 -J {} cp {} destination_folder/ POSIXly:
LC_ALL=C find . ! -name . -prune ! -name '*.*' -type f -exec sh -c ' exec cp "$@" destination_folder/' sh {} +
a,a.txt,b,b.txt...