I want to copy a xml file from one remote box to a bunch of other remote boxes, but I only want it to copy the file it there is currently an existing file already in place. How can I do that?
One more question, is there a way to export out the list of only if the file exists?
I'm not sure about using cygwin but as it's windows you can just use xcopy.
xcopy \\remotebox1\file.xml \\remotebox2\file.xml /U /Y
That will copy the file only if it exists in the destination already, and will overwrite without prompting.
You can just do it using regular DOS commands, there's no need to resort to cygwin:
IF EXIST filename_on_remote_server COPY /Y filename_on_local_server filename_on_remote_server
Or, if you are writing a BASH script for cygwin, then you can refer to this answer.
This will work from inside in a bash file:
if [ -f /path/to/file.xml ]; then
cp /path/to/file.xml /path/to/other/file.xml
fi
A one-liner for the command line might be:
[ -f /path/to/file.xml ] && cp /path/to/file.xml /path/to/other/file.xml
Related
How to simply recreate copy/paste functionality like in gui environments?
My typical scenario for copying file/directory in Linux console is:
cp source_path target_path
Sometimes paths are relative, sometimes absolute, but I need to provide them both. It works, but there are situations where I would like to recreate scenario from gui which is:
1. go to source directory
2. copy file/directory
3. go to target directory
4. paste file/directory
I imagine something like
cd source_directory_path
copy_to_stash source_name
cd target_directory_path
paste_from_stash [optional_new_target_name]
I know that there is a xclip app, but a documentation says that it copies content of a file, not a file handle. Also, I can use $OLDPWD variable and expand it when I copy file, but this is not a solution without some cumbersome.
Is there some simple, general, keyboard only, not awkward to use equivalent?
I've also asked the same question on superuser and answer that I've received is good enough for me.
In short: two additional scripts and temporary variable to hold intermediate value.
Below is a code and link to original answer.
#!/bin/bash
# source me with one of:
# source [file]
# . [file]
# Initialize
sa_file=
sa(){
# Fuction to save a file in the current PWD
if [[ -e "$PWD/$1" ]]; then
sa_file=$PWD/$1
echo "Saved for later: $sa_file"
else
echo "Error: file $PWD/$1 does not exist"
fi
}
pa(){
# Paste if file exists, to $1 if exists
if [[ -e "$sa_file" ]]; then
if [[ $1 ]]; then
cp -v "$sa_file" "$1"
else
cp -v "$sa_file" .
fi
else
echo "Error: file $sa_file does not exist, could not copy"
fi
}
https://superuser.com/a/1405953/614464
The way I see it your only option is to write a script to do all of those steps. You could easily implement the clipboard functionality by copying the file to the /tmp directory before copying again from it.
This should work as intended.
Usage: script [from] [to]
filename=$(basename "$0")
tmpfile=/tmp/$filename.$RANDOM
cd $(dirname "$0")
cp $tmpfile $filename
cd $(dirname "$1")
cp $tmpfile $(basename "$1")
One option: you can either copy-paste the filename using mouse, using copy-paste feature from your terminal emulator (e.g. Konsole or GNOME Terminal), but this: 1) requires a GUI since the terminal emulator software run in GUI; 2) well, requires a mouse.
Another option: utilize shell tab completion. You still need to type the filename, but not all of it.
Third option, and this is closer to how you work in a GUI file explorer: use a TUI-based file explorer, e.g. the dual-pane style Midnight Commander. You can use arrow keys (if you turn on the Lynx-like motion setting, which is very recommended) to quickly navigate the directory tree. Then select files using the Insert, +, -, or * keys, then copy/move files from one pane to another. It's very convenient. In fact half of the time I spend in CLI, I spend in MC.
Hi I am writing a tcl script to automate the task in linux. In that I want to copy files.
The command is
cp -r source destination. I have tried using
puts [cp -rf source destination]. But I am getting error saying invalid command cp. How will I write it in tcl script.
To run an external program from your script, you should use the exec command:
puts [exec cp -r $source $destination]
However, for the specific case of copying a directory from one place to another you can use the built-in file copy command (which works with directories as well as files):
file copy $source $destination
There are multiple files in /opt/dir/ABC/ named allfile_123-abc allfile_123-def allfile_123-ghi allfile_123-xxx.
I need the files to be named new_name-abc.pgp new_name-def.pgp new_name-ghi.pgp new_name-xxx.pgp and then moved to /usr/tst/output
for file in /opt/dir/ABC/allfile_123* ;
do mv $file /usr/tst/output/"$file.pgp";
rename allfile_123 new_name /usr/tst/output/*.pgp ; done
I know the above doesn't work because $file = /opt/dir/ABC/allfile_123*. Is it possible to make this work, or is it a different command instead of 'for loop'?
This is for the Autosys application in which the jil contains a command to pass to the command line of a linux server running bash.
I could only find versions of each part of my question but not altogether and I was hoping to keep it on the command line of this jil. Unless a script is absolutely necessary.
No need for the loop, you can do this with just rename and mv:
rename -v 's/$/.pgp/' /opt/dir/ABC/allfile_123*
rename -v s/allfile_123/new_name/ /opt/dir/ABC/allfile_123*
mv /opt/dir/ABC/new_name* /usr/tst/output/
But I'm not sure the rename you are using is the same as mine.
However,
since the replacement you want to perform is fairly simple,
it's easy to do in pure Bash:
for file in /opt/dir/ABC/allfile_123*; do
newname=new_name${file##*allfile_123}.gpg
mv "$file" /usr/tst/output/"$newname"
done
If you want to write it on a single line:
for file in /opt/dir/ABC/allfile_123*; do newname=new_name${file##*allfile_123}.gpg; mv "$file" /usr/tst/output/"$newname"; done
I am trying to create a sh/bash script to rename files according to directory names. For example if there is a directory named Linux, the files inside should be renamed Linux.jpg, Linux2.jpg, Linux3.jpg etc. There is also more then 1 directory within the main example directory with other files also.
it must work within my copy script if possible, i am copying the directory across to another folder, then when that is done i'd like the rename process to happen. Here is my copy script:
#!/bin/sh
if cp -r "$1" "$2"
then echo "copy success!"
else echo "copy failed!"
fi
It seems this question is already answered here, please check it out:
Shell script to rename files based on directory names
Files are being transferred to a directory on my machine by FTP protocol. I need to SCP these files to another machine & delete them on completion.
How can I detect if file trasfer by FTP has been done & the file is safe to do SCP?
There's no reliable way to detect completion of the transfer. Some clients send ALLO command and pass the size of the file before actually uploading the file, but this is not a definite rule, so you can't rely on it. All in all, it's possible that the client streams the data and there's no definite "end" of file on its side.
If the client is under your control, you can make it upload files with extension A and after upload rename the files to extension B. And then you transfer only files with extension B.
You can do a script like this:
#!/bin/bash
EXPECTED_ARGS=1
E_BADARGS=65
#Arguments control
if [ $# -lt $EXPECTED_ARGS ]
then
echo "Usage: `basename $0` <folder_update_1> <folder_update_2> <folder_update_3> ..."
exit $E_BADARGS
fi
folders=( "$#" )
for folder in ${folders[#]}
do
#Send folder or file to new machine
time rsync --update -avrt -e ssh /local/path/of/$folder/ user#192.168.0.10:/remote/path/of/$folder/
#Delete local file or folder
rm -r /local/path/of/$folder/
done
It is configured to send folders. If you want files need make little changes on script as:
time rsync --update -avrt -e ssh /local/path/of/$file user#192.168.0.10:/remote/path/of/$file
rm /local/path/of/$file/
Rsync is similar to scp. I prefer use rsync but you can change it.