0

I want to create a shell script that will rename all .txt files from a specific directory in remote server by using SFTP (will download the files first then rename in remote server). Please check the attempt below:

sftp user@host <<EOF
cd $remoteDir
get *.txt
ls *.txt | awk '{printf "rename %s %s.done\n",$0,$0 ;}' 
exit
EOF

From the statement ls *.txt | awk '{printf "rename %s %s.done\n",$0,$0 ;}' it will generate and print out a list of rename command, my question is, how to run these command generated from awk printf?

Newbie
  • 1,584
  • 9
  • 33
  • 72

2 Answers2

0

You are trying to rename files on the server but you only know what commands to run after you have downloaded the files.

The simple option would be to run two sftp sessions. The first downloads the files. Then you generate the rename commands. Then you run a second sftp session.

However it is possible to do both in one session:

#!/bin/bash

(
    # clean up from any previous run
    rmdir -f syncpoint

    # echo commands are fed into the sftp session
    # be careful with quoting to avoid local shell expansion
    echo 'cd remoteDir'
    echo 'get *.txt'
    echo '!mkdir syncpoint'

    # wait for sftp to create the syncpoint folder
    while [ ! -d syncpoint ]; do sleep 5; done

    # the files have been downloaded
    # now we can generate the rename commands
    for f in *.txt; do
        # @Q is a bash (v4.4+) way to quote special characters
        echo "rename ${f@Q} ${f@Q}.done"
        # if not available, single-quoting may be enough
        #echo "rename '$f' '$f'.done"
    done

    # clean up
    rmdir syncpoint

) | sftp user@host
jhnc
  • 11,310
  • 1
  • 9
  • 26
  • +1 for cleverness but "it can be done" does not mean "it should be done". A tool which lets you run `sftp` in a subprocess would be much simpler and more robust. My choice would be Python but I'm sure it can be done with any modern scripting language. – tripleee Feb 27 '19 at 12:41
  • @tripleee I can believe it's more robust if you're doing errorhandling. I don't know python but looking at paramiko docs, seems like one might end up with similar logic to this but just with more boilerplate. Probably worth it if problem is more complicated, not convinced simpler... :-) – jhnc Feb 27 '19 at 13:01
  • There's a separate `pysftp` library which I believe should allow this to be done fairly succinctly. – tripleee Feb 27 '19 at 13:04
  • yes, doesn't seem like a huge amount of boilerplate, although `get *.txt` doesn't seem completely trivial: https://stackoverflow.com/q/36329931/10971581 – jhnc Feb 27 '19 at 13:13
  • Maybe also mention that `${f@Q}` is a Bash v4.4+ feature. – tripleee Feb 27 '19 at 13:19
-3

Hello Newbie please use this

sftp user@host <<EOF
cd $remoteDir
ls *.txt | awk '{printf "mv %s %s.done\n",$0,$0 ;}' | sh
exit
EOF
Alpy
  • 759
  • 6
  • 9