awk ou sed para analisar elementos do caminho do diretório

1

Digamos que eu tenha vários diretórios de tamanho variável na forma

/tmp/(1) I. First Majuscule Roman Numeral/01. First Arabic Numeral/a. First Grapheme
/tmp/(2) II. Second Majuscule/03. Third Arabic/d. Fourth

que quero analisar para que a saída seja

I.01.a.
II.03.d.

Qual é a solução awk e / ou sed?

    
por Kent Davis 29.03.2018 / 18:58

3 respostas

1

Supondo que esses são os diretórios somente abaixo de /tmp :

$ find /tmp -mindepth 3 -type d -print | sed -e 's/\.[^/]*/./g' -e 's/^.* //' -e 's#/##g'
I.01.a.
II.03.d.

O comando find localiza os diretórios no nível 3 e imprime seu caminho completo. O resultado deste passo é

/tmp/(1) I. First Majuscule Roman Numeral/01. First Arabic Numeral/a. First Grapheme
/tmp/(2) II. Second Majuscule/03. Third Arabic/d. Fourth

O comando sed faz três coisas:

  1. substitui tudo de um ponto até a próxima barra com um ponto, criando

    /tmp/(1) I./01./a.
    /tmp/(2) II./03./d.
    
  2. remove o bit até o primeiro espaço,

    I./01./a.
    II./03./d.
    
  3. remove as barras,

    I.01.a.
    II.03.d.
    
por 29.03.2018 / 19:28
2

Não há necessidade de awk ou sed, realmente; bash globbing e testes de expressão regular podem fazer isso:

for d in /tmp/*/*/*
do
  if [[ $d =~ ^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/([^[:space:]]*).*/([^[:space:]]*) ]]
  then
    printf "%s\n" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
  fi
done

Exemplo de saída:

I.01.a.
II.03.d.

A expressão regular interna divide-se em três componentes:

  1. ^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/

O nome do arquivo deve iniciar ^ com /tmp/ e, em seguida, alguns caracteres não espaciais devem ser seguidos por um espaço seguido por (captura) caracteres não espaciais e, em seguida, qualquer coisa até uma barra invertida

  1. ([^[:space:]]*).*/

... seguido por (capturando isso) caracteres não espaciais, depois qualquer coisa até uma barra invertida

  1. ([^[:space:]]*)

... seguidos por (capturando isso) caracteres não espaciais) - seguidos por ... nada que nos interessa.

Bash salva os bits capturados na matriz BASH_REMATCH, com base na ordem dos parênteses de captura.

    
por 29.03.2018 / 19:36
0

Para o inferno, já que não há uma resposta awk ainda ...

awk -v FS="" '
{
    for (i=1;i<=NF;i++) {
        if ($i==" " || $i=="/") {
            part=""
        } else if ($i==".") {
            printf "%s.", part
        } else {
            part=part FS $i
        }
    }
}
END { printf "\n" }'

Define o separador de campos para "" para que possa percorrer cada caractere. Procura por "" ou "/" no caractere atual e redefine o proprietário (variável de peça) se encontrar um. Se encontrar "." imprima o suporte, caso contrário, concatene o caractere atual no suporte. Acrescenta alimentação de linha quando é feito.

Saída no exemplo:

I.01.a.
II.03.d.
    
por 29.03.2018 / 19:41