Copy and rename in the same time (also change filename, not only path):
cp program3.cpp homework6.cpp
Rename only:
mv program3.cpp homework6.cpp
Answer from Cornelius on askubuntu.comCopy and rename in the same time (also change filename, not only path):
cp program3.cpp homework6.cpp
Rename only:
mv program3.cpp homework6.cpp
If you want to have the files permanently linked use the ln command instead of cp
ln program3.cpp homework6.cpp
This puts a file descriptor (hard link) under the name homework6.cpp to the same file location as program3.cpp
Copy and rename file from shell script
copy and rename file in linux bash - Stack Overflow
shell - How can I copy a file in a bash script and rename it while copying and place it in the same directory - Unix & Linux Stack Exchange
linux - Copying a file from one directory to the next and changing the name - Unix & Linux Stack Exchange
Videos
In an -exec predicate, the symbol {} represents a path that is being considered, starting at one of the starting-point directories designated in the command. Example: start/dir2/Preview.json. You can form other file names by either prepending or appending characters, but whether that makes sense depends on the details. In your case, appending produces commands such as
cp start/dir2/Preview.json start/dir2/Preview.jsonQA
which is a plausible command in the event that start/dir2/Preview.json exists. But cp does not automatically create directories in the destination path, so the result of prepending characters ...
cp start/dir2/Preview.json QAstart/dir2/Preview.json
... is not as likely to be accepted -- it depends on directory QAstart/dir2 existing.
I think what you're actually looking for may be cp commands of the form ...
cp start/dir2/Preview.json start/dir2/QAPreview.json
... but find cannot do this by itself.
For more flexibility in handling the file names discovered by find, pipe its output into another command. If you want to pass them as command-line arguments to another command, then you can interpose the xargs command to achieve that. The command on the receiving end of the pipe can be a shell function or a compound command if you wish.
For example,
# Using ./* instead of * ensures that file names beginning with - will not
# be misinterpreted as options:
find ./* -type f -name 'Preview.json' |
while IFS= read -r name; do # Read one line and store it in variable $name
# the destination name needs to be computed differently if the name
# contains a / character (the usual case) than if it doesn't:
case "${name}" in
*/*) cp "${name}" "${name%/*}/QA${name##*/}" ;;
*) cp "${name}" "QA${name}" ;;
esac
done
Note that that assumes that none of your directory names contain newline characters (the read command would split up newline-containing filenames). That's a reasonably safe assumption, but not absolutely safe.
Of course, you would generally want to have that in a script, not to try to type it on the fly on the command line.
If you want to copy Preview.json to a new name like Performance.json, across multiple folders, you can do it like this directly on terminal:
find . -type f -name 'Preview.json' | while read -r file; do \
dir="${file%/*}"; \
cp "$file" "$dir/Performance.json"; \
done
This works like finds every Preview.json in subfolders and copies it to Performance.json in the same folder
For example, If you have .....
./project1/Preview.json
./project2/Preview.json
..... Youโll get
./project1/Performance.json
./project2/Performance.json
Itโs just Bash string slicing:
${file%/*} = everything before the last slash โ folder
${file##*/} = just the filename
Check man bash or Google "bash parameter expansion"
This is a pretty basic question but Iโve been struggling getting this working for some reason. I am trying to copy a file from one directory to another and renaming it along with the copy. This is being done inside of a shell script, and I have a variable called $filename that stores the NEW file name. Here is the code snippet:
filename="IRcam_fpga_cksm_${checksum}_ver_${version}.pdb"
#filename="This_is_a_file.txt"
echo "filename: ${filename}"
cp ./par/ircam_fpga/designer/impl1/*.pdb output/pl/$filenameThe output of the echo command on the console is:
.pdbname: IRcam_fpga_cksm_A415_ver_0x0081
But the file that gets copied to the new directory does not have the correct name. When I use the version of $filename that is commented out, it works perfectly fine.
No need for bash here, any standard sh interpreter implementation will do:
#! /bin/sh -
ret=0
for file do
dir=$(dirname -- "$file")
case
dir/ # handle / and // specially
esac
base=$(basename -- "$file")
name=${base%.*}
name=${name:-$base} # don't consider .bashrc the extension in /foo/.bashrc
ext=${base#"$name"}
new_file=
{name}_copy
file" "$new_file" || ret=$?
done
exit "$ret"
(assumes the file and dir names don't end in newline characters).
(of course, that will also work with bash since bash is one of those standard sh interpreters.)
For a bash-specific solution, you could try:
#! /bin/bash -
ret=0
re='^((.*/)?[^/])(([^/]*)(\.))?([^/]*)/*$'
for file do
if [[ $file =~ $re ]]; then
if [[ ${BASH_REMATCH[5]} ]]; then
suffix=_copy.${BASH_REMATCH[6]}
else
suffix=${BASH_REMATCH[6]}_copy
fi
cp -- "$file" "${BASH_REMATCH[1]}${BASH_REMATCH[4]}$suffix" || ret=$?
else
printf >&2 '%s\n' "$0: Error: refusing to copy $file"
ret=1
fi
done
exit "$ret"
Since the OP is asking for a bash solution. Here is one that does.
#!/bin/bash
if [[ ! -f $1 && $(($# != 1)) ]]; then
printf '%s\n' "Provide a filename"
exit 1
fi
inFile="$1"
fileExt="${1#*.}"
destFile="${1%.*}"
cp -- "$inFile" "${destFile}_copy.$fileExt" # As suggested, so the files that start with a dash are not ignored.
You can use the following:
for file in *
do
name="${file%.*}"
extension="${file##*.}"
cp $file ${name}_my${extension}
done
Note that ${file%.*} returns the file name without extension, so that from hello.txt you get hello. By doing ${file%.*}_my.txt you then get from hello.txt -> hello_my.txt.
Regarding the extension, extension="${file##*.}" gets it. It is based on the question Extract filename and extension in bash.
If the shell variable expansion mechanisms provided by fedorqui's answer look too unreadable to you, you also can use the unix tool basename with a second argument to strip off the suffix:
for file in *.txt
do
cp -i "$file" "$(basename "$file" .txt)_my.txt"
done
Btw, in such cases I always propose to apply the -i option for cp to prevent any unwanted overwrites due to typing errors or similar.
It's also possible to use a direct replacement with shell methods:
cp -i "$file" "${file/.txt/_my.txt}"
The ways are numerous :)
You should be able to do just
cp -R /tf/Custom_App /tf/Custom_App_backups/Custom_App_2017-12-21
However, if the target directory already exists, this would append the final part of the source path to the destination path, creating
/tf/Custom_App_backups/Custom_App_2017-12-21/Custom_App, and then copy the rest of the tree within that.
To prevent this, use /tf/Custom_App/. as the source. Of course, in that case you might want to rm -r /tf/Custom_App_backups/Custom_App_2017-12-21 first, if you don't want older files lying around there after the copy.
The difference between /some/dir and /some/dir/. was discussed a while back in cp behaves weirdly when . (dot) or .. (dot dot) are the source directory
Alternatively, you can do it like so:
mkdir /tf/Custom_App_backups/Custom_App_2017-12-21 # prepare the target location
cp -R /tf/Custom_app/. /tf/Custom_App_backups/Custom_App_2017-12-21 # copy only the contents
This will allow you to specify your custom location beforehand. Also, notice that it uses the suffix /. This allows you to only copy the contents and exclude its containing folder -- in this case it is the Custom_app folder.
You can use the cp command with the -a option
-a, --archive
same as -dR --preserve=all
And then use a for loop to rename all files while copying them:
for file in Erp*etf; do
cp -a $file destinationDirectory/${file%%-*}.etf
done
Ready. Start this command in the source directory.
Explanation: The %%-* will cut off all the characters after the first occurence of a hyphen/minus - and the .etf at the end again adds the file extension.
Well, and as a one liner, put it all in one line. :-) Like this
for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done
pax can do this all at once. You could do:
cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data
pax preserves times by default, but can add -pe to preserve everything (best done as root) or -pp to preserve permissions , eg:
cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data
Otherwise (pax isn't usually available by default), surely it is better to do a copy then a rename:
cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf
This way there is not a different process started for each file.