captura o segundo campo e o último campo da string

0

temos arquivos com o seguinte formato de nome de arquivo

VER_ {NOME DO ARQUIVO} _ {VERSÃO}

exemplo

  VER_collect_important_info.pl_1.0.2

queremos capturar apenas o número "FILE NAME" e "VERSION"

como remover o primeiro _ e o último _ no nome do arquivo então podemos capturar o "FILE NAME" e "VERSION", (com sed / awk ou perl one-liner)

exemplo

 echo VER_collect_important_info.pl_1.0.2 | <some syntax>

 collect_important_info.pl  1.0.2
    
por jango 18.01.2018 / 06:18

7 respostas

2

O Perl vem muito mais naturalmente para mim do que as alternativas mais leves:

echo VER_collect_important_info.pl_1.0.2 | perl -pe 's/^[^_]*_(.*)_(.*)$/$1 $2/'

Se não importa que isso use um processo de peso maior que o necessário, eu paro por aí.

sed pode fazê-lo, no entanto, parece ruim ter que ter que escapar de elementos básicos como colchetes:

echo VER_collect_important_info.pl_1.0.2 | sed 's/VER_\(.*\)_\(.*\)/ /'
    
por 18.01.2018 / 09:09
1

Isso deve fazer o truque

$ echo VER_collect_important_info.pl_1.0.2 | sed 's/_/ /' | sed -r 's/(.*)_/ /' | awk -F" " '{print $2"\t"$3}'

O primeiro sed está substituindo a primeira ocorrência de _ e o segundo sed faz isso com a última ocorrência de _ e finalmente awk para imprimir

    
por 18.01.2018 / 06:32
1
$ echo 'VER_collect_important_info.pl_1.0.2' | 
    perl -F_ -lane 'print join("_", @F[1..@F-2]), " ", @F[@F-1]'
collect_important_info.pl 1.0.2

Observação: as matrizes perl começam em 0, não em 1, de modo que o índice da matriz do segundo campo é [1] , não [2] .

Isso divide a entrada em uma matriz ( @F ), separada por _ caracteres de sublinhado. Em seguida, imprime o segundo até o segundo e último campo ( @F[1..@F-2] ) associado por sublinhados, seguido de um espaço e, em seguida, o último campo ( @F[@F-1] ).

    
por 18.01.2018 / 06:46
1
Solução

find + bash :

Arquivos de amostra:

$ ls -1 VER_*_[0-9]*[0-9]
VER_collect_important_info.pl_1.0.2
VER_collect_some_info.pl_3.4.2
find . -type f -name "VER_*_[0-9]*[0-9]" -exec \
        bash -c 'v=${1##*_}; f=${1#*_}; f=${f%_*}; echo $f $v' _ {} \;

A saída:

collect_some_info.pl 3.4.2
collect_important_info.pl 1.0.2
    
por 18.01.2018 / 07:46
1

Com o awk você pode usar:

echo VER_collect_important_info.pl_1.0.2 | awk -F '_' '{for (i=2; i<NF; i++) {{printf $i} if (i!=NF-1) printf "_"} printf " " $NF "\n"}'
    
por 18.01.2018 / 08:04
0

O resultado foi mencionado usando a combinação de sed e awk

echo VER_collect_important_info.pl_1.0.2 |sed -r "s/_/ /1"| sed "s/_/ /3"| awk '{print $2,$NF}'
    
por 18.01.2018 / 16:33
0

Basta executar este script perl e passar o diretório para ver como é o argumento:

#!/usr/bin/perl

use strict;
use warnings;

my $dir = $ARGV[0];
my @files = 'find $dir -type f -name "VER_*_[0-9]*[0-9]"';

my $all_files;
foreach my $file (@files) {
    $file =~ /VER_(.*)_(.*)/;
    $all_files .= $1."  ".$2."\n";
}

print $all_files if ($all_files);

Exemplo:
Eu executei esse script passando o diretório atual (.) Como argumento para ele (que contém VER_collect_important_info.pl_1.0.3 ).

[mask@cent ~]$ perl separate_file_version.pl .  
collect_important_info.pl  1.0.3
    
por 22.02.2018 / 09:26

Tags