3

I have a text file abc.txt and its contents are:

   /lag/cnn/org/one.txt
   /lag/cnn/org/two.txt
   /lag/cnn/org/three.txt

If I use:

$ tar -cvf allfiles.tar -T abc.txt

I'm getting the tar of files in the list. Similarly is it possible to copy those files in abc.txt to a folder?

I tried this:

$ cp --files-from test1.txt ./Folder

But it is not working.

Mano
  • 289

5 Answers5

6

Note that the standard (POSIX/Unix) command to create a tar file is pax. pax combines the traditional cpio and tar commands.

To create a tar file, use the write mode:

pax -w < abc.txt > allfiles.tar

To copy instead, use the copy mode:

pax -rw < abc.txt Folder/

Note that it recreates the directory structure into Folder. If you want to flatten it, you could do:

pax -rws '|.*/||' < abc.txt Folder/

(see the man page if you want to copy permissions or other attributes as well. pax expects one file per line, which means files whose name contains newline characters cannot be copied that way, some pax implementations support a -0 option to allow a NUL delimited file list instead).

With cpio:

cpio -pd < abc.txt Folder/

With GNU tar:

tar -cf - -T abc.txt | (cd Folder && tar xf -)

Another option to allow any character in file names is (with GNU cp):

xargs cp -t Folder < abc.txt

(that flattens the directories).

xargs expects a blank (space, tab, newline) separated list, when you can escape those separators with backslash, single or double quotes. So you can have a list like:

"file with space"
other-file
'file with "quote" and
newline'
5

I'm not sure where you read that cp has a --files-from option, but I certainly don't have that using GNU coreutils 8.22.

As long as your filenames have no newlines in them, you can do this (with bash4+):

mapfile -t files < test1.txt
cp -- "${files[@]}" Folder/

If you don't have bash4+, then you can manually populate an array and use it (or just call cp directly from within read for each file, but that will be slower):

while IFS= read -r file; do
    files+=( "$file" )
done < test1.txt
cp -- "${files[@]}" Folder/
Chris Down
  • 125,559
  • 25
  • 270
  • 266
2

You can achieve this by a simple bash script:

for i in $(cat path_to_abc.txt)
do 
  cp "$i" path_to_Folder
done

A safer way, that can deal with arbitrary file names:

while IFS= read -r file; do 
    cp -- "$file" path_to_Folder
done
terdon
  • 242,166
Vombat
  • 12,884
  • 1
    This will break if any filename contains a character from $IFS, which is quite possible. – Chris Down Dec 22 '13 at 09:06
  • @ChrisDown His/her files have simple names! ;) :P – Vombat Dec 22 '13 at 09:19
  • 1
    I don't know how you can tell that from a list of three placeholder filenames. – Chris Down Dec 22 '13 at 09:52
  • @ChrisDown, that also breaks on globbing characters (star, question mark, left square bracket) and filenames starting with -. set -f; IFS=$'\n'; cp -- $(cat path_to_abc.txt) path_to_folder wouldn't have those issues. (the format of the list file can't allow newlines anyway) – Stéphane Chazelas Dec 22 '13 at 14:02
2

cp doesn't have a --files-from option (at least, GNU cp doesn't) but rsync does:

rsync --files-from abc.txt -av / Folder/

The / is used if your test.txt file contains files with absolute paths. Otherwise it should be the root of the source.

If your files are zero-terminated rather than newline-terminated you should include the --from0 option.

Chris Davies
  • 116,213
  • 16
  • 160
  • 287
0

If you just want to copy the files with similar names you can use this :

Go to the source folder

cp $(ls  | grep 'one' | grep 'two') /tmp/

So all the files contains the string one and two in their names will be copied to tmp directory

AdminBee
  • 22,803