Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash loop in a directory

Tags:

bash

heredoc

ftp

I have a directory that contain Javascript files, some of this javascript files begin the suffixe "T_" as T_test.js

I would like to loop the directory and invoice by FTP all the files that don't begin by "T_".

# FTPexport script :

#!/bin/bash

HOST="ftp-server.net" # sample
USER="me" # sample
PASSWORD="pss" # sample

ftp -inv $HOST <<EOF
user $USER $PASSWORD

cd www/public/JS
for f in 
do 
  put f;
done
bye 

Thanks if someone can help me.

I work on Linux with a server in Linux.

And in fact, my problem, I have many directories with JS, CSS and Html, and sometime I forget to upload some files. I would like to automate the process to upload news or recent files, without to upload the files who are used as tests, and often this test files are marked as T_*.js

like image 375
Jérémie Rousseau Avatar asked Dec 16 '25 12:12

Jérémie Rousseau


1 Answers

I would like to loop the directory and invoice by FTP all the files that don't begin by "T_"

"Files that don't begin by 'T_'" can be identified in various ways, but one of the easiest would be by globbing: ? [^T]* T[^_]*. If you don't want to worry about files named exactly T then you can simplify that to [^T]* T[^_]*. And that plays nicely with an interactive ftp command, as these do not ordinarily provide looping commands, but they do, typically, provide an mput command that recognizes globs. Thus, you might use this variation on your example code:

#!/bin/bash
# Note: to be useful, the above shebang line must be the very first in the script
#
# FTPexport script :

HOST="ftp-server.net"
USER="me"
PASSWORD="pss"

ftp -inv "$HOST" <<EOF
user $USER $PASSWORD
cd www/public/JS
mput [^T]*
mput T[^_]*
bye
EOF 

It is possible, however, that that will sometimes cause one or both mput commands to fail on account of no matching files. I don't think that would be fatal, but if you go with something like this then you should definitely test that behavior in advance.

Alternatively, you could take more control by doing the globbing directly in the shell script. Something like this, say:

#!/bin/bash
# Note: to be useful, the above shebang line must be the very first in the script
#
# FTPexport script :

HOST="ftp-server.net"
USER="me"
PASSWORD="pss"

# Collect the names of the files to transfer in an array
shopt -s nullglob
files=(? [^T]?* T[^_]*)

# Stop now if the array is empty
if [[ ${#files[@]} -eq 0 ]]; then
  echo "no files to transfer" 1>&2
  exit
fi

# Connect to the FTP server and upload each file via its own 'put' command
ftp -inv "$HOST" <<EOF
user $USER $PASSWORD
cd www/public/JS
${files[@]/#/
put }
bye
EOF 

The substitution reference in that internal FTP script perhaps bears a little additional explanation:

  • A substitution reference operating on an array subscripted by @ performs the substitution on each element of the array, and expands to the results, in order, separated by the first character of $IFS (ordinarily a space character).
  • A # at the beginning of the substitution string anchors it to the beginning, and an otherwise-empty substitution string results in the replacement being inserted at the beginning of the source string.
  • The replacement starts with a (literal) newline to separate the put commands for FTP. This will also produce an initial newline, resulting in an empty command, but that should be harmless in this situation.
  • The replacement continues with a put command keyword and a space to separate it from the file name.

Note also that the globs used in these examples will match directory names, too, which would probably produce unwanted behavior. You could consider other ways to form the source-file array if that's an issue for you.

like image 87
John Bollinger Avatar answered Dec 19 '25 05:12

John Bollinger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!