Description
Given a datafile where each line of it is a file path. We want to convert that file to a sequence of FTP `put' commands to upload them. Instead of just `put'ting them directly, if a bunch of files are to be uploaded to the same directory, we want to
  • `cd' to that directory first,
  • then each `put' each one of them with only the basenames, without the directory part.
Besides,
  • Each line of the datafile begins with ./.
  • To `cd' to another directory, a relative path is used.
Raw Input Desired Output
./top/index.html
./top/lecture1.html
./top/lecture2.html
./pr1/sub1/slide1.html
./pr1/sub1/slide2.html
./pr1/sub2/slide1.html
./pr1/sub3/sub31/slide1.html
./pr2/slide1.html
./pr2/slide2.html
cd ./top
put index.html
put lecture1.html
put lecture2.html
cd ./../pr1/sub1
put slide1.html
put slide2.html
cd ./../../pr1/sub2
put slide1.html
cd ./../../pr1/sub3/sub31
put slide1.html
cd ./../../../pr2
put slide1.html
put slide2.html
Script and Comments
Script1
[ 1] G
[ 2] /^\.((\/[^/\n]+)*)\/[^\n]+\n\.\1\/[^/]+$/{
[ 3] s/\n.*//
[ 4] h
[ 5] s/^.*\//put /
[ 6] b
[ 7] }
[ 8] h
[ 9] s/\n.*//
[10] x
[11] s/\n\.?/ \n/
[12] :loop
[13] s/\n\/[^/]+\//\/..\n\//
[14] /\n\/.*\//b loop
[15] s/^\.((\/[^/]+)*)\/([^\n]+) ([^\n]*)\n.*/cd .\4\1\nput \3/
Comments
  1. If the current object will be uploaded to the same directory with the previous one, no `cd' is required. Therefore, keeping the previous object's path in the Hold Space is required.
  2. The `Hold Space' is abbreviated to HS.
  3. The `-r ' option of GNU sed must be used to make it interpret REs as EREs.
  4. Command `G' of Step [1] appends the previous object's path after the current one, separating them with a newline character.
  5. If the current and the previous object are with the same directory part,
    • Step [3] removes the appended part, rendering only the current one.
    • Step [4] keeps the current path to HS, which will be used when processing next path.
    • Step [5] inserts the `put' command.
    • Command `b' of Step [6] makes sed jump to the end of the script, print the processed line, and then start a new cycle.
  6. Otherwise, the directory part of the current object is different from the previous one:
    • After Steps [8] thru [10], the Pattern Space contains the current path followed by the previous path, separated by a new line character,
    • and the Hold Space contains the current path.
  7. For example, if the current path is ./pr2/slide1.html, and the previous one is ./pr1/sub3/sub31/slide1.html,
    • the loop consisting of Steps [12] thru [14] is used to convert ./pr1/sub3/sub31/slide1.html to /../../..,
    • then Step [15] does the final job.