cp: omitting directory, for copying only files, sed

Cyrille Lefevre cyrille.lefevre-lists@laposte.net
Mon Nov 8 00:21:00 GMT 2010

Le 07/11/2010 17:49, Edgar Matzinger a écrit :
> On 7 Nov 2010, at 14:22, David wrote:
>> Den 06-11-2010 15:12, Edgar Matzinger skrev:
>>> I ran this script (on MacOSX):
>>> #!/bin/sh
>>> W="\/Users\/edgarm\/tmp\/$1\/."
>>> echo $W
>>> sed -n 's/^File[ ]*\([^ ][^ ]*\).*/\"\1\" '"$W"'/p' < $2 | xargs echo X:
> I would replace your script with this one:
> #!/bin/sh
> W="\/Users\/edgarm\/tmp\/$1\/."
> echo $W
> sed -n -e '/^File/H' -e '${x; s:\n: :g; s:File ::g; s:\(.*\):\1 "'$W'":;
> p; }' < $2 | xargs cp
> What does it do?
> - -e '/^File/H'    When pattern buffer starts with 'File', append it to
> hold buffer
> - -e '${        When at the last line, start a function
>  x;        Exchange hold and pattern buffer
>  s:\n: :g;    Replace newline with a space
>  s:File ::g;    Delete 'File '
>  s:\(.*\):\1 "'$W'":;
>         Append $W to pattern buffer
>  p; }'        Print pattern buffer and close function
> Note: The pattern buffer is also the input buffer.

take care that the hold buffer may be limited in size,
see "info sed Limitations" for details.
that mean that legacy sed may break if the file list is too long.
gnu sed has no such limitations, but remember you such limitations.

well, 2 alternatives w/o such limitation :

this one is a little less performant than the one provided due to
multiple fork, but a little simple :

sed -ne 's|\\|/|g;/^File /s///p' $2 | xargs -I{} echo cp {} "$W"

cp ../test/file1.txt /path/to
cp ../test/file2.txt /path/to

-n	don't print anything except if asked for (see p)
s|\\|/|g \ => /
/^File / do the following subsitution only on mached line
s///	substitute 'File ' w/ nothing, yep, if the search pattern
	is not provided, the last one is used
p	print the pattern buffer if a substitution has occured
there is no ; between /^File/...p, this is normal.

this one needs a GNU cp which support the -t option :

sed -ne 's|\\|/|g;/^File /s///p' $2 | xargs echo cp -t "$W"

cp -t /path/to ../test/file1.txt ../test/file2.txt


Cyrille Lefevre

Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

More information about the Cygwin mailing list