1

I am sending files from one server to another using scp . I need to rename files after sending that .So I use following command for each file

scp original-hc.db user@host:/dir/original-hc_1.db

I want to send all files using a single command with renaming files . Like

scp *.db user@host:/dir/(actual file name before extension)_1.db
Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
  • 2
    I don't believe what you're asking for is possible in a single command. As I understand it scp or any copy command for that matter will allow multiple files to copy but requires a single destination and does not allow for renaming unless you are only copying a single file. There are commands to rename lots of files at once, e.g. rename but not one command that combines both. – Zachary Brady Aug 31 '16 at 17:41

2 Answers2

7

This can easily be achieved with a loop

for f in *.db
do
    scp "$f" user@host:/dir/"${f%.db}"_1.db
done

The ${f%.db} construct strips off the .db suffix from $f.

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

scp can't rename files when copying multiple files to a directory, so you'll need to use some other tool in addition or instead to perform the pattern-based renaming.

If you have SFTP access and not just SCP access, then you can use SSHFS to make the remote files appear on your local machine. This allows you to use any file copy-and-renaming tool.

mkdir mnt
sshfs user@host:/dir
pax -rw -pe -s'/\.db$/_1.db/' *.db mnt
fusermount -u mnt

Instead of pax (which is POSIX but sometimes not installed by default on Linux though it's always available as a package), you might use GNU or BSD tar, zsh's zcp, etc. Or just a loop that does the copy:

for x in *.db; do
  cp -p "$x" "mnt/${x%.db}_1.db"
done

You can use the loop method even if you don't have SSHFS, but then you have to use scp in the loop.

for x in *.db; do
  scp -p "$x" "user@host:/dir/${x%.db}_1.db"
done

Setting up an SSH connection for each time can be a little slow. With OpenSSH, you can open the connection once and then piggyback on it. See Using an already established SSH channel

Another method (requiring full shell access on the server) is to archive the files and copy the archive, and apply a renaming step when archiving or when extracting. For example, if you have GNU tar locally (which is always the case on non-embedded Linux and often available, perhaps as gtar, on other unix variants):

tar -cf - --transform '/\.db$/_1.db/ *.db | ssh user@host 'cd /dir && tar -xf -'

With BSD tar, replace --transform by -s. If you have a very limited tar locally but GNU tar or BSD tar on the server, you can do the renaming on the server side instead.

You might want to insert a step of compression if the network bandwidth is the bottleneck. With the archive method, you can insert steps in the pipeline:

tar -czf - --transform '/\.db$/_1.db/ *.db | ssh user@host 'cd /dir && gunzip | tar -xf -'

Or you can do the compression at the SSH level, by passing the -C option to ssh, sshfs or scp.

  • I've just tested and scp DOES rename the file. scp src $name@$ip:/dst creates a dst file on the remote. – P i Oct 23 '22 at 14:34
  • 2
    @Pi scp can copy one file to another file with a different name. It can't apply a renaming rule, which is what the question was about. I can see how the sentence was confusing out of context, so I've clarified it. – Gilles 'SO- stop being evil' Oct 23 '22 at 18:51