How to copy and add prefix to file names in one step?
Solution 1
a for
loop:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
I often add the -v
option to cp
to allow me to watch the progress.
Solution 2
You can use shell globbing:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
The for variable in GLOB
format will expand the glob to all matching files/directories (excluding hidden-ones) and iterate over them, saving each in turn as $variable
(in the example above, $f
). So, the command I show will iterate over all non-hidden files, copying them and adding the prefix.
Solution 3
Here is a one-liner using xargs
, tr
and globbing. Might have some value.
echo *.c | tr ' ' '\n' | xargs -n1 -I{} cp "{}" "PREFIX{}"
This returns all files matching *.c
as a space-separated string. Next, tr
turns the extra spaces into newlines (N.B. did not test file names with spaces**). Then, xargs
gets populated with each file name, and runs cp
with the appropriate name and prefix.
*.c
can be modified for other, useful globs. Other prefixes in the xargs
and cp
part can be used as well.
**for those with spaces in their filenames:
(requires find
that supports -print0
)
Similar to above, we can use find
to output a null-seperated list of files, and tweak xargs
with a flag to separate on null
find . -name '*.c' -print0 | xargs -0 -n1 -I{} cp "{}" "PREFIX{}"
Related videos on Youtube
BlackCat
Updated on September 18, 2022Comments
-
BlackCat almost 2 years
I want to copy and rename multiple c source files in a directory.
I can copy like this:
$ cp *.c $OTHERDIR
But I want to give a prefix to all the file names:
file.c --> old#file.c
How can I do this in 1 step?
-
don_crissti about 7 years
-
don_crissti about 7 yearsSame here, don't loop over
find
's output -
Scott - Слава Україні over 5 yearsAnd, if you had tested this with filenames containing spaces, you would have seen it fail.
-
TonyH over 5 yearsThanks for call-out. I knew it probably failed but thought I had already procrastinated through enough of my workday with the first pass. 😀
-
alexandernst almost 5 yearsIf I do
for f in /foo/bar/*.c
,$f
will contain the entire path, instead only the name of the file. How can I obtain only the name of the file? -
terdon almost 5 years@alexandernst either
cd /foo/bar/; for f in *c
, or usefor f in /foo/bar/*.c; do name=${f##*/} ...
orname=$(basename "$f")
.