#! /usr/bin/gawk -f # Last edited on 2024-04-02 18:19:04 by stolfi # Filter that splits the directory and file name in a list of files # with size, date, and optional checksum. # # Assumes that the last field in the line is a full pathname. # replaces it with the file name, a space, and the directory. # If the directory is empty, writes "." instead. # Each input line may have 1, 3, or 4 fields, interpreted as follows: # 1 field -- pathname. # 3 fields: size, date, and pathname. # 4 fields: checksum, size, date, and pathname # # The date should be in the format "yyyy-mm-dd-hhmmss" or # "yyyy-mm-dd-hhmmss.nnnnnnnnn". The checksum should be # zero-padded to 10 digits. Blank lines and '#'-comment lines # are copied unchanged. BEGIN { nf = -1; # Determined by first rescord. hasns = -1; # True iff the time has nanoseconds. } /^ *([#]|$)/ { print; next; } // { if (nf < 0) { # First record: if ((NF != 1) && (NF != 3) && (NF != 4)) { data_error(("invalid num fields " NF)); } nf = NF; } else { # Not first record: if (NF != nf) { data_error(("inconssistent num fields " nf " " NF)); } } if (nf == 1) { ck = ""; sz = ""; dt = ""; pn = $1; } else if (nf == 3) { ck = ""; sz = $1; dt = $2; pn = $3; } else if (nf == 4) { ck = $1; sz = $2; dt = $3; pn = $4; } else { prog_error("duh?") } if (ck != "") { if ((ck !~ /^[0-9]+$/) || (length(ck) != 10)) { data_error(("bad checksum '" ck "'")); } } if (sz != "") { if ((sz !~ /^[0-9]+$/) || (length(sz) > 14)) { data_error(("bad size '" sz "'")); } } if (dt != "") { if (dt ~ /^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]-[0-2][0-9][0-6][0-9][0-6][0-9]$/ ) { thins = 0 } else if (dt ~ /^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]-[0-2][0-9][0-6][0-9][0-6][0-9][.][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$/ ) { thisns = 1 } else { data_error(("bad date '" dt "'")) } if ((hasns != -1) && (thisns != hasns)) { data_error(("inconsistent nanoseconds")) } hasns = thisns } if (pn ~ /[\/]/) { dir = pn; gsub(/[\/][^\/]*$/, "", dir) nam = pn; gsub(/^.*[\/]/, "", nam) } else { dir = ""; nam = pn } if (dir == "") { dir = "." } if (nf == 1) { printf "%s %s\n", nam, dir } else if (nf == 3) { printf "%14d %s %s %s\n", sz, dt, nam, dir } else if (nf == 4) { printf "%010d %14d %s %s %s\n", ck, sz, dt, nam, dir } else { prog_error("duhhh?") } next } function data_error(msg) { printf "%s:%d: ** %s\n", FILENAME, FNR, msg > "/dev/stderr" printf " %s\n\n", $0 > "/dev/stderr" exit(1) } function prog_error(msg) { printf "%s:%d: ** program error: %s\n", FILENAME, FNR, msg > "/dev/stderr" exit(1) }