From: Nicolas Boisselier Date: Tue, 16 Jan 2018 22:00:43 +0000 (+0000) Subject: bin/csv2human X-Git-Url: https://git.nbdom.net/?a=commitdiff_plain;h=24f77f81d3e06bb93578f65aa17b849badeaa335;p=nb.git bin/csv2human --- diff --git a/bin/csv2human b/bin/csv2human new file mode 100755 index 00000000..6d7968fa --- /dev/null +++ b/bin/csv2human @@ -0,0 +1,212 @@ +#!/usr/bin/env perl +use strict; +use warnings; +################################################################################# +# +# VERSION +# +################################################################################# +my $VERSION = '0.0.1'; +# NB 16.01.18 +# - create script + +################################################################################# +# +# GLOBALS +# +################################################################################# +my ($NAME) = $0 =~ m,([^/]+)$,; + +################################################################################# +# +# ARGS +# +################################################################################# +my $VERBOSE = $main::VERBOSE = 1; +my $DEBUG = $main::DEBUG = 0; + +my %Opt = ( + 'header' => 1, + 'sep' => "\t", +); +get_options(\%Opt); +#@help() unless @ARGV; +$main::_DATA_ = undef; + +################################################################################# +# +# BEGIN +# +################################################################################# +#use Data::Dumper; print Dumper(\%Opt); +use Encode; +binmode( STDOUT, "utf8:" ); + +my @len = (); +my @lines = (); + +while (<>) { + + my @F = split($Opt{sep}); + + for (my $i=0;$i<@F;$i++) { + chomp($F[$i]); + #$F[$i] =~ s/^\r//; + $F[$i] = Encode::decode_utf8($F[$i]); + my $l; + $len[$i] = $l if ( $l = length($F[$i]) ) >= ($len[$i] || 0); + } + + push @lines, [@F]; +} + +exit unless @lines; + +my $tot = @lines - ($Opt{header} ? 0 : 1); + +my $t = -1; +my $format = "| ".join(" | ",map {$t+=$_+3; "\%-".$_."s"} @len)." |".chr(10); + +my $sep_line = "+".join("+",map {("-"x($_+2))} @len)."+".chr(10); +print $sep_line; + +my $i = 0; +while ($_ = shift @lines) { + printf $format,@$_; + print $sep_line if $Opt{header} and !$i++; +} + +print $sep_line; +print "$tot Records\n" if $VERBOSE; + +################################################################################# +# +# END +# +################################################################################# +exit 0; + +################################################################################# +# +# Functions +# +################################################################################# +sub help { +#------------------------------------------------------------------------------ +# Print help and exit +#------------------------------------------------------------------------------ + + require 'Pod/Usage.pm' unless $INC{'Pod/Usage.pm'}; + + # Substitutions + sub pod_env { + my $v = ''; + eval '$v = ref(\\'.$_[0].') eq "ARRAY" ? join(" ",'.$_[0].') : '.$_[0].'; return defined $v ? $v : qq|UNDEF|;'; + return $v; + } + + $main::_DATA_ =~ s/([@\$][A-Z_a-z\{\}]+)/pod_env($1)/eg; + + my $in; + open($in,'<',\$main::_DATA_); + + open(STDOUT,"|perl -pe 's/\.$$//g'".(($ENV{PAGER}||'') eq 'less' ? "|less -FRi" : "")); + my $opts = { + -input => $in, + -ouput => \*STDOUT, + -exitval => 'noexit', + -sections => [qw(SYNOPSIS DESCRIPTION OPTIONS)], + -verbose => ($Opt{'help'} ? 99 : 3), + }; + + Pod::Usage::pod2usage($opts); + close $in; + close STDOUT; + + exit 0; +} + +#------------------------------------------------------------------------------ +# Print version and exit +#------------------------------------------------------------------------------ +sub version { print "$NAME: version [$VERSION]\n"; exit 0; } + +#------------------------------------------------------------------------------ +# Get options from pod +#------------------------------------------------------------------------------ +sub get_options { + + use Getopt::Long qw(:config no_ignore_case no_auto_abbrev); + + my @Opt; + + sub pod_opt { + local $_; + my $o = shift; + $o =~ s/(=.|[\+\-\!]$)//; + $o = join(", ",map{"-$_"} split(/[\|,:;]/,$o)); + return "$o"; + } + + while () { + s/option\[([^\]]+)\]/push(@Opt,$1) and pod_opt($1)/eg; + $main::_DATA_ .= $_; + } + + GetOptions($_[0],@Opt) || exit -1; + + help() if $_[0]{'help'} or $_[0]{'man'}; + version() if $_[0]{'version'}; + + $main::VERBOSE = $VERBOSE = $_[0]{'verbose'} if defined $_[0]{'verbose'}; + $main::DEBUG = $DEBUG = $_[0]{'debug'} if defined $_[0]{'debug'}; + +} + +__DATA__ + +=head1 NAME + +$NAME - Alternative to linux command column, format csv tab style rows + +=head1 SYNOPSIS + +Quick usage! + +=over + +=item $NAME --sep ',' --noheader FILE + +=item $NAME --help + +=back + +=head1 DESCRIPTION + +Description! + +=head1 OPTIONS + + -option[header|h!] Print or not header separotor after first row + -option[sep|s=s] Separtor + -option[verbose|v+] Verbose mode: increase the verbosity level. + -option[debug+] Debug mode: increase the verbosity level. + -option[version|V] Print version (default: $VERSION) + -option[help|?] Print a brief help message and exits. + -option[man] Print the manual page and exits. + +=cut + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2018 Nicolas Boisselier + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +See . + +=head1 AUTHOR + +Nicolas Boisselier + +=cut diff --git a/etc/profile.d/functions b/etc/profile.d/functions index 07c83bf6..f51cf939 100644 --- a/etc/profile.d/functions +++ b/etc/profile.d/functions @@ -553,71 +553,71 @@ exit $diff ? 0 : 1; } -csv2human() { - shell_help "Usage: $FUNCNAME [PERL_REGEXP --sep|-s (default: tab)] [--noheader|-nh]" "$@" && return; - local sep noheader; - sep='\t'; - noheader=0; - local files='' - - while [ $# -gt 0 ]; do - - if [ -e "$1" ]; then - files="$files $1" - shift - continue - fi - - case "$1" in - --sep|-s) - sep=$2; - shift - ;; - --noheader|-nh) - noheader=1 - ;; - *) - echo "Unknow option: $1 at $0!"; - return 1 - ;; - - esac - - shift - - done - - [ -z "$@" ] || sep="$@"; - - cat $files | perl -MEncode -F"$sep" -ane 'BEGIN { - $noheader = shift @ARGV; - @len = (); @lines = (); - binmode( STDOUT, "utf8:" ); -}; -for ($i=0;$i<@F;$i++) { - chomp($F[$i]); - $F[$i] =~ s/^\r//; - $F[$i] = Encode::decode_utf8($F[$i]); - $len[$i] = $l if ( $l = length($F[$i])) >= $len[$i]; -} -push @lines, [@F]; -END { - exit unless @lines; - $i = 0; - $t = -1; - $tot = @lines - ($noheader ? 0 : 1); - $format = "| ".join(" | ",map {$t+=$_+3; "\%-".$_."s"} @len)." |".chr(10); - $sep_line = "+".join("+",map {("-"x($_+2))} @len)."+".chr(10); - print $sep_line; - while ($_ = shift @lines) { - printf $format,@$_; - print $sep_line if !$noheader and !$i++; - } - print $sep_line; - print "$tot Records\n"; -} -' $noheader -} +# NB 16.01.18 csv2human() { +# NB 16.01.18 shell_help "Usage: $FUNCNAME [PERL_REGEXP --sep|-s (default: tab)] [--noheader|-nh]" "$@" && return; +# NB 16.01.18 local sep noheader; +# NB 16.01.18 sep='\t'; +# NB 16.01.18 noheader=0; +# NB 16.01.18 local files='' +# NB 16.01.18 +# NB 16.01.18 while [ $# -gt 0 ]; do +# NB 16.01.18 +# NB 16.01.18 if [ -e "$1" ]; then +# NB 16.01.18 files="$files $1" +# NB 16.01.18 shift +# NB 16.01.18 continue +# NB 16.01.18 fi +# NB 16.01.18 +# NB 16.01.18 case "$1" in +# NB 16.01.18 --sep|-s) +# NB 16.01.18 sep=$2; +# NB 16.01.18 shift +# NB 16.01.18 ;; +# NB 16.01.18 --noheader|-nh) +# NB 16.01.18 noheader=1 +# NB 16.01.18 ;; +# NB 16.01.18 *) +# NB 16.01.18 echo "Unknow option: $1 at $0!"; +# NB 16.01.18 return 1 +# NB 16.01.18 ;; +# NB 16.01.18 +# NB 16.01.18 esac +# NB 16.01.18 +# NB 16.01.18 shift +# NB 16.01.18 +# NB 16.01.18 done +# NB 16.01.18 +# NB 16.01.18 [ -z "$@" ] || sep="$@"; +# NB 16.01.18 +# NB 16.01.18 cat $files | perl -MEncode -F"$sep" -ane 'BEGIN { +# NB 16.01.18 $noheader = shift @ARGV; +# NB 16.01.18 @len = (); @lines = (); +# NB 16.01.18 binmode( STDOUT, "utf8:" ); +# NB 16.01.18 }; +# NB 16.01.18 for ($i=0;$i<@F;$i++) { +# NB 16.01.18 chomp($F[$i]); +# NB 16.01.18 $F[$i] =~ s/^\r//; +# NB 16.01.18 $F[$i] = Encode::decode_utf8($F[$i]); +# NB 16.01.18 $len[$i] = $l if ( $l = length($F[$i])) >= $len[$i]; +# NB 16.01.18 } +# NB 16.01.18 push @lines, [@F]; +# NB 16.01.18 END { +# NB 16.01.18 exit unless @lines; +# NB 16.01.18 $i = 0; +# NB 16.01.18 $t = -1; +# NB 16.01.18 $tot = @lines - ($noheader ? 0 : 1); +# NB 16.01.18 $format = "| ".join(" | ",map {$t+=$_+3; "\%-".$_."s"} @len)." |".chr(10); +# NB 16.01.18 $sep_line = "+".join("+",map {("-"x($_+2))} @len)."+".chr(10); +# NB 16.01.18 print $sep_line; +# NB 16.01.18 while ($_ = shift @lines) { +# NB 16.01.18 printf $format,@$_; +# NB 16.01.18 print $sep_line if !$noheader and !$i++; +# NB 16.01.18 } +# NB 16.01.18 print $sep_line; +# NB 16.01.18 print "$tot Records\n"; +# NB 16.01.18 } +# NB 16.01.18 ' $noheader +# NB 16.01.18 } mail_relay_closed() { shell_help "Usage: $FUNCNAME MAIL_SERVER" "$@" && return; diff --git a/lib/php/out/sh.php b/lib/php/out/sh.php index ac0dbc76..11f18afa 100644 --- a/lib/php/out/sh.php +++ b/lib/php/out/sh.php @@ -2,19 +2,29 @@ if (!class_exists('out')) return; return [ 'preff' => self::p('preff',""), + 'kuc' => (int)self::p('kuc',false), + 'nl' => (int)self::p('nl',false), + 'rec' => self::p('rec',';'), + 'sep' => self::p('sep',' '), 'row' => function(&$o,&$r) { $line = []; foreach ($r as $k=>$v) { if (!preg_match('/^[a-zA-Z\w_]+$/',$k)) continue; + $v = self::scalar($v); + $v = str_replace('"','\\"',$v); $v = str_replace('$','\\$',$v); $v = str_replace('`','\\`',$v); $v = str_replace("\r",'',$v); $v = str_replace("\n",'"$\'\\\\n\'"',$v); - $line[] = $o['preff']."$k=\"$v\""; + + if ($o['kuc']) $k = strtoupper($k); + + $line[] = $o['preff'] . "$k=\"$v\""; } - if ($line) echo join(' ',$line).";\n"; + + if ($line) echo join($o['sep'],$line) . $o['rec'] . "\n"; } ]; ?> diff --git a/www/dbq/html/default.js b/www/dbq/html/default.js index 687f7e66..62a03c81 100644 --- a/www/dbq/html/default.js +++ b/www/dbq/html/default.js @@ -133,7 +133,7 @@ document.addEventListener("DOMContentLoaded", function() { document.querySelector("th.delete").appendChild(a); } - document.querySelectorAll("body > h1 a.db, body > h1 a.table").forEach(function(e) { + if (document.querySelector("body.action-ls")) document.querySelectorAll("body > h1 a.db, body > h1 a.table").forEach(function(e) { var base = window._dbq[e.className+'.base'].replace(/\/[^\/]+$/,''); //if (base == '') base = '/'; var url = base + (base == '' ? '/ls' : '') + '.json';