I have a folder with a lot of files. I want to copy all files which begin with of these names (separated by space):
abc abd aer ab-x ate
to another folder. How can I do that?
I have a folder with a lot of files. I want to copy all files which begin with of these names (separated by space):
abc abd aer ab-x ate
to another folder. How can I do that?
With csh
, tcsh
, ksh93
, bash
, fish
or zsh -o cshnullglob
, you can use brace expansion and globbing to do that (--
is not needed for these filenames, but I assume they are just examples):
cp -- {abc,abd,aer,ab-x,ate}* dest/
If you'd rather not use brace expansion, you can use a for loop (here POSIX/Bourne style syntax):
for include in abc abd aer ab-x ate; do
cp -- "$include"* dest/
done
If you have a very large amount of files, this might be slow due to the invocation of cp
once per include. Another way to do this would be to populate an array, and go from there (here ksh93
, zsh
or recent bash
syntax):
files=()
includes=(abc abd aer ab-x ate)
for include in "${includes[@]}"; do
files+=( "$include"* )
done
cp -- "${files[@]}" dest/
abc,abd,aer,ab-x,ate
(the list shown here ). Is there a way to omit the commas? Or a way to insert the commas automatically
– user69453
Jun 19 '14 at 10:24
A note about brace expansion vs globbing.
Brace expansion is not globbing (though the distinction is not as clear in csh/tcsh where it originated as in other shells). It is performed before globbing.
So, when you do:
cp {a,b}* /dest
It is first expanded to:
cp a* b* /dest
That means that the shell will have to expand two globs, that is get the full list of files twice and see which match the pattern twice.
With zsh
, that also means that if any of the glob doesn't match any file, the whole command is cancelled (which you can work around by enabling the cshnullglob
option to behave like in csh).
That also means that if you have
cp {a,ab}* /dest
cp
will copy the ab*
files twice.
That's different from the:
cp @(a|b)* /dest
of ksh
or bash -O extglob
or zsh -o kshglob
, or
cp (a|b)* /dest
of zsh
. There, it's only one glob, so it will be more efficient, and files will only be included once.
With zsh
, if you've got the list of prefixes in an array:
prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest
(above, the prefixes are treated as globs). That is join the elements of the arrays with |
and consider the result as a glob (~
).
If the list is big, what you may find is that executing cp
fails with an "arg list too long" error. In that case, you can use zsh
builtin version of cp
which you can by loading the zsh/files
module (zmodload zsh/files
).
For example I have these files in current directory:
1-s2.0-S0038092X0000058X-main.pdf ANNDHW.pdf HPcalculation2
1-s2.0-S0306261999000422-main.pdf ANNlee.pdf HPcalculation3
ANNCanada.pdf HPcalculation HPcalculation4
I want to move all the files starting from HP to folder: ./NewFolder/
I can do:
cp ./HP* ./NewFolder/
./HP*
will tell linux that I am interested in all the files starting from HP. The reverse is when I am interested in moving all the files ending with .pdf
. I can put *
in front of the .pdf
:
cp ./*.pdf ./NewFolder/
Simply you can do
cp abc* abd* aer* ab-x* ate* DestinationPath
A solution to your extended problem can be
Copy all with
cp `cat list0.txt` DestinationPath # Needs no whitespace in the filenames
or, better,
while read -r file; do cp "$file" dest/ ; done < list0.txt
Notes:
One Package.deb
-r
it protect you from escape sequences.
-r Backslash does not act as an escape character. The backslash is considered to be part of the line. In particular, a backslash- newline pair may not be used as a line continuation
while read file; do cp "$file" dest/ ; done < list0.txt
instead.
– terdon
Jun 19 '14 at 11:40
read -r
. BTW this example was related to a list of package names of ubuntu with no whitespace inside.@terdon Thx for the spot.
– Hastur
Jun 19 '14 at 12:00
IFS= read -r
for the leading and trailing blank characters not to be removed. Also note that the newline character is as valid as any in a filename.
– Stéphane Chazelas
Jun 19 '14 at 12:13
abc abd aer ab-x ate
– Avinash Raj Jun 19 '14 at 10:19