bash + como anexar caminho ao final da linha de acordo com o caminho existente

5

O seguinte arquivo de configuração ( exemplo 1 ) não está configurado como deveria ser.

Cada linha no arquivo deve conter o /grid/sdX ( a to z ) conforme descrito no exemplo 2 .

Eu preciso encontrar uma maneira de escrever um script bash para essa tarefa. Como anexar o /grid/sdX ausente no final das linhas?

exemplo 1

more dfs_data_dir_mount.hist


/grid/sdk/hadoop/hdfs/data,/
/grid/sdi/hadoop/hdfs/data,/
/grid/sdh/hadoop/hdfs/data,/
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/
/grid/sde/hadoop/hdfs/data,/grid/sde
/grid/sdd/hadoop/hdfs/data,/grid/sdd
/grid/sdb/hadoop/hdfs/data,/grid/sdb
/grid/sdf/hadoop/hdfs/data,/grid/sdf
/grid/sdg/hadoop/hdfs/data,/

resultados esperados (exemplo 2)

/grid/sdk/hadoop/hdfs/data,/grid/sdk
/grid/sdi/hadoop/hdfs/data,/grid/sdi
/grid/sdh/hadoop/hdfs/data,/grid/sdh
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/grid/sdj
/grid/sde/hadoop/hdfs/data,/grid/sde
/grid/sdd/hadoop/hdfs/data,/grid/sdd
/grid/sdb/hadoop/hdfs/data,/grid/sdb
/grid/sdf/hadoop/hdfs/data,/grid/sdf
/grid/sdg/hadoop/hdfs/data,/grid/sdg
    
por yael 31.12.2017 / 20:53

5 respostas

6

sed solução:

sed -Ei 's~^(/[^/]+/[^/]+)(.*,)/$~~' dfs_data_dir_mount.hist
  • ~ - tratado como sed separador do subcomando
  • [^/]+ - corresponde a um ou mais caractere (s), exceto barra /
  • ^ $ - são o início e o fim da linha, respectivamente
por 31.12.2017 / 21:05
5

Consegui fazer isso com o seguinte comando awk:

awk -F'/' '{OFS="/";}{print $1,$2,$3,$4,$5,$6,"grid",$3}' input

awk

  • -F'/' - Delimitar entrada de /
  • {OFS="/";} - Delimitar a saída em /
  • {print $1,$2,$3,$4,$5,$6,"grid",$3}' - Imprimir /grid/sd*/hadoop/hdfs/data,/ (campos retirados da entrada) e grid/sd* (inserir manualmente grid e adicionar o campo 3 novamente)
por 31.12.2017 / 20:59
5

awk :

awk -F/ -v OFS='/' '!$NF {$0=$0 $2 OFS $3}; 1'
  • -F/ -v OFS='/' define o separador de campos de entrada e saída como /
  • !$NF {$0=$0 $2 OFS $3}; 1 se o último campo estiver vazio, estamos reescrevendo o registro no formato desejado. 1 é vital em awk e é imprimir os registros.

Exemplo:

% cat file.txt 
/grid/sdk/hadoop/hdfs/data,/
/grid/sdi/hadoop/hdfs/data,/
/grid/sdh/hadoop/hdfs/data,/
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/
/grid/sde/hadoop/hdfs/data,/grid/sde
/grid/sdd/hadoop/hdfs/data,/grid/sdd
/grid/sdb/hadoop/hdfs/data,/grid/sdb
/grid/sdf/hadoop/hdfs/data,/grid/sdf
/grid/sdg/hadoop/hdfs/data,/

% awk -F/ -v OFS='/' '!$NF {$0=$0 $2 OFS $3}; 1' file.txt
/grid/sdk/hadoop/hdfs/data,/grid/sdk
/grid/sdi/hadoop/hdfs/data,/grid/sdi
/grid/sdh/hadoop/hdfs/data,/grid/sdh
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/grid/sdj
/grid/sde/hadoop/hdfs/data,/grid/sde
/grid/sdd/hadoop/hdfs/data,/grid/sdd
/grid/sdb/hadoop/hdfs/data,/grid/sdb
/grid/sdf/hadoop/hdfs/data,/grid/sdf
/grid/sdg/hadoop/hdfs/data,/grid/sdg
    
por 31.12.2017 / 21:08
3

Perl oneliner:

perl -i.bak -pe 's;^/(grid/sd.)/hadoop/hdfs/data,/\K$;$1;' input

Corresponda a string, pegando o grid/sdX do início no caminho, depois esqueça ( \K ) a parte principal da string, mas ainda corresponda ao final da linha $ , que é então substituída por a parte capturada pelos parênteses e disponível em $1 .

-i.bak faz as alterações no local e salva o arquivo original com a extensão .bak .

$ cat input
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/
/grid/sde/hadoop/hdfs/data,/grid/sde
$ perl -i.bak  -pe 's:^/(grid/sd.)/hadoop/hdfs/data,/\K$:$1:' input
$ cat input
/grid/sdc/hadoop/hdfs/data,/grid/sdc
/grid/sdj/hadoop/hdfs/data,/grid/sdj
/grid/sde/hadoop/hdfs/data,/grid/sde
    
por 31.12.2017 / 21:36
1

Aproximação de perl alternativa (baseada em campo) usando o operador de concatenação de seqüência de caracteres .= :

perl -F/ -lpe '$_ .= "$F[1]/$F[2]" unless defined $F[7]' dfs_data_dir_mount.hist
    
por 31.12.2017 / 21:53