App-Bin4TSV
view release on metacpan or search on metacpan
scripts/csel view on Meta::CPAN
#!/usr/bin/perl -T
use 5.008 ; use strict ; use warnings ; # 5.011
use Getopt::Std ; getopts '~i:=!d:0:h:np:rt:' , \my %o ;
#use List::MoreUtils qw/any none/ ;
use List::Util qw [ max ] ;
use Encode qw/decode_utf8/ ;
use Memoize ;
use Data::Dumper ;
use Term::ANSIColor qw[ :constants] ; $Term::ANSIColor::AUTORESET = 1 ;
memoize ( 'sCols' ) ; # ãã®ããã°ã©ã ã«ç¾ãã sCols 颿°ãé«éåããã
$| = 1 if $o{'!'} ;
my %cream ; # åã®çªå·ã®é
åãæ ¼ç´ããã
# $cream{p} åºåããããæå®ããåçªå·ã®ç¡åé
å
# $cream{d} åé¤ããããæå®ããåçªå·ã®ç¡åé
å
# $cream{h} å
é ã«ç§»åããããã«æå®ããåçªå·ã®ç¡åé
å
# $cream{t} æ«å°¾ã«ç§»åããããã«æå®ããåçªå·ã®ç¡åé
å
my $emp = $o{'0'} // '' ; ; # åå¨ããªãã»ã«ãåç
§ããã¨ãã«è¡¨ç¤ºããæåå
my %colNamePos ; # åã®ååããã1å§ã¾ãã®åçªãåç
§ãã
my $isep = $o{i} // "\t" ; # å
¥åã®åºåãæå
my $split_limit = $isep eq '' ? 0 : -1 ; # split ã§ä½¿ããsplit//ã¯LIMIT=0ã«ããªãã¨ãçµæã«ç©ºæååã®å¤ãæå¾ã«çãã
my $osep = $isep eq '' && $o{n} ? ' ' : $isep ; # åºåã®åºåãå
& init ; # ãªãã·ã§ã³ã«ã¤ãã¦ã®å¦ç
& main ; # ã¡ã¤ã³ã®å¦ç printColsMain
exit 0 ;
# åæåå¦çã®çºã®å±éã®å¦ç
sub expand ( $ ) { # ã¾ã ã³ã³ãã§åå², # 次㫠.. ãå±éããã # æå¾ã«æ£ã®æ°ã¯ 1ãå¼ãã
#print BRIGHT_BLUE Dumper ["cNP=",%colNamePos] ;
return () if ! defined $_[0] ;
my @gr = split /,/ , $_[0] ; # grain ç©ç©ã®ç²ã®ã¤ãããexpandedãèããããã¹ãã«é·éãã
my $l = scalar @gr ;
for ( reverse 0 .. $#gr ) {
if ( $gr [ $_ ] =~ m|(.+)\.\.(.+)| ) { # *æ«å°¾* ããæ°åãå±éããã
my ($c1,$c2) = ($1,$2) ;
if ( $o{'='} ) { $c1 = $colNamePos { $c1 } ; $c2 = $colNamePos { $c2 } } #; print "\$c1=$c1, \$c2=$c2\n" } ;
splice @gr , $_ , 1 , ( $c1 <= $c2 ? $c1 .. $c2 : reverse $c2 .. $c1 ) ;
} else {
$gr[ $_ ] = $colNamePos { $gr[ $_ ] } if $o{'='} ;
}
}
#print CYAN Dumper [@gr], Dumper ;
#print CYAN join ", " , @gr ;
#@gr = grep { $_ ne 0 } @gr ; # 0ã¯åãé¤ãã$0 ã -ptdhã®å¼æ°ã«0ãä¸ããã®ã¯ããã«ãã®æå¶ã主ç®çã¨ãªãã
grep { $_ = $_ - ( $_ > 0 ? 1 : 0 ) } @gr ; # 1å§ã¾ãã§ä¸ããããåçªå·ã0å§ã¾ãã«ããããã ããè² ã®æ°ã¯å¤ããªãã
return @gr ;
}
# åæåå¦çãã³ãã³ã弿°ã®ãªãã·ã§ã³ã«ã¤ãã¦ã®å¦ç ; 2åã®é¢æ°
sub init {
if ( ! scalar grep { defined } @o{qw/p d h t n/} ) { *STDOUT= *STDERR ; &HELP_MESSAGE ; exit }
}
# åæ°ãã¨ã«ãã©ã®åãè¦ãããã®åçªã®ç¡åé
åãè¿ãã
sub sCols ( $ ) {
sub none ( &@ ) { my $f = shift; foreach ( @_ ) { return 0 if $f->(); } return 1 ; }
sub drop ( $@ ) { my$o = shift @_ ; return grep { my$x=$_;none{$x==$_} @_ } @{$o} } ; # []
my $W = $_[0] ; # åè¡ã®ãã»ã«(å)ãã®åæ°ãä¸ããããã
$cream {p} = [ 0 .. $W - 1 ] if ! defined $o{p} ;
my @p_ = @{ $cream{p} } ;
my @d_ = @{ $cream{d} } ;
my @h_ = @{ $cream{h} } ;
my @t_ = @{ $cream{t} } ;
$_ = $W == 0 || abs ($_) >= $W && ! $o{r} ? -1 : $_ % $W for @p_ , @d_ , @h_ , @t_ ; # -ræå®ã§åç´ã«ãµã¤ã¯ãªãã¯
@p_ = drop \@p_ , @d_ , @h_ , @t_ ;
@h_ = drop \@h_ , @d_ ; # -h,-tã§æå®ãããåã§ãã-dã§æå®ããããã®ã¯æ¶ããã
@t_ = drop \@t_ , @d_ ; #
my @out = (@h_ , @p_ , @t_) ;
#print join ". " , @{ $cream{p}} , "#" ; # map ( $_ // "u" , @out, @{$cream{p}}) , "\n" ;
if ( $o{'~'} ){
my @tmp = (-1) x ( 1 + max (@out , @{$cream{p}} ) ) ; # = map { $out[$_] } 0 .. $#out ;
for ( 0 .. $#out ) { $tmp [ $out[$_] ] = $_ }
@out = @tmp ; #print join ", " , map ( $_+1, @out) , "\n" ;
}
return [ @out ] ;
}
# åè¡ã®åºåå¦çã sCols颿°ãå¼ã³åºãã¦ã鏿ããã-n ã§åçªå·ãä»ããã
sub line ( ) {
chomp ;
$_ = decode_utf8 ( $_ ) if $isep eq '' ; # å
¥åãSTDINã¨ã¯éããªãã®ã§ binmode ã使ãã decode_utf8
my @F = split /$isep/ , $_ , $split_limit ; #use Data::Dumper ; print scalar @F , Dumper [@F];
@F = map { $_ + 1 . ":$F[$_]" } 0 .. $#F if $o{n} ; # -n ã§åçªå·ãã³ãã³ãä»ãã¦åºå
push @F , $emp ; # $F[-1] ã§åç
§ãã
print join ( "$osep" , @F [ @{ sCols $#F } ] ) , "\n" ;
}
# main
sub main {
binmode STDOUT ,":utf8" if $isep eq '' ; # æååä½ã§å¦çããå ´åãutf8ã¨ãã¦ã®æ±ããããã
# ä¸è¡ç®ã㤠-= ãæå®ãããå ´åã®å¦ç
if ( $o{'='} ) {
$_ = <> ;
chomp ;
my $c = 0 ;
$colNamePos { $_ } = ++ $c for split /$isep/ , $_ , $split_limit ; # <-- å岿ååã«æ°ãã¤ããã
$cream{ $_ } = [ expand $o{$_} ] for qw/p d h t/ ;
line ; # <-- -
}
else {
$cream{ $_ } = [ expand $o{$_} ] for qw/p d h t/ ;
}
#print BRIGHT_GREEN Dumper [%colNamePos] ;
# å¼ãç¶ãå¦çã-=ãç¡ãå ´åã«ã¯ãããããå§ã¾ãã
while ( <> ) {
line
} ;
}
## ãã«ãã®æ±ã
sub VERSION_MESSAGE {}
sub HELP_MESSAGE {
use FindBin qw[ $Script ] ;
$ARGV[1] //= '' ;
open my $FH , '<' , $0 ;
while(<$FH>){
s/\$0/$Script/g ;
print $_ if s/^=head1// .. s/^=cut// and $ARGV[1] =~ /^o(p(t(i(o(ns?)?)?)?)?)?$/i ? m/^\s+\-/ : 1;
}
close $FH ;
exit 0 ;
}
=encoding utf8
=head1
csel -- Easier interface than cut/AWK to handle TSV/CSV input,
with the options such as -p(Printing)/-d(Deleting)/-h(moving to Head)/-t(moving to Tail).
AWKè¨èªãã³ãã³ãcutãããåã®æ½åºãç°¡åã«æ¸ããã³ãã³ãã©ã¤ã³ãæä¾ããã
æ¦è¦:
( run in 1.504 second using v1.01-cache-2.11-cpan-39bf76dae61 )