Bloomy
July 8, 2011, 12:29pm
1
Hi.
I have a list with file names like
testfile1.wav
testfile2.wav
testfile3.wav
and a folder that contains a large number of wav files (not only the ones on the list).
I would like to copy the files whose names are on the list from the wav file directory to a new directory.
I tried to write a Python script for this, but it doesn't work and I wondered if there's an easier option to do that.
Cheers,
Kat
If GNU cp is available (if you're on Linux for example) and if the filenames do not contain pathological characters (newlines or white spaces):
< list xargs cp -t target_dir --
If the filenames contain white spaces and you have GNU cp (this is will be much slower if the number of files is high):
< list xargs -I{} cp -t target_dir -- {}
This is similar, but noisy:
while IFS= read -r; do
cp -- "$REPLY" target_dir
done < list
Another option, if the filenames do not contain embedded newlines
and the total length of their names is below the ARGS_MAX limit
of your system:
( IFS=$'\n'; cp -- $(<list) target_dir )
If your shell doesn't expand ansi strings $'...'
, use a literal newline:
(
IFS='
'
cp -- $(<list) target_dir
)
1 Like
Thanks! I tried the first option but I received the error
cp: target `testfile.wav' is not a directory
I executed it like this:
cd'ed into the wav file directory and then:
< ../list.data xargs cp -- -t ./target_directory
Sorry, there was an error in the commands I posted. Try the new versions.
The double dash -- marks the end of options, so it should be after the -t option and its argument.
Hi,
I didnt understand what is difficult in this.. I have a suggestion.
for file in `cat list_file ` /* list_file contains the wav files you want to copy
do
cp source_dir/$file new_dir
done
That is a useless use of cat and useless use of backticks , inherently dangerous because any file too long for a shell variable to hold will have some of its contents silently lost. It's also very inefficient. There's a much better way to do this, which doesn't attempt to store the entire file in memory at once, and uses pure shell built-ins:
while read LINE
do
...
done < filename
1 Like