Aqui estão as strings disponíveis em ksh88?

6

Eu queria extrair 3 palavras de uma variável em 3 variáveis diferentes no script ksh. Eu usei essa linha no ksh93 e funcionou bem:

read A B C <<< $line

Obteve este erro para o comando acima enquanto o executava no ksh88:

syntax error at line ## : '<' unexpected

Como executar a mesma ação no ksh88?

    
por Pratik Mayekar 18.06.2018 / 14:14

2 respostas

13

Não, as strings aqui não estão disponíveis em ksh88 e pdksh . No mais recente ksh93 (original AT & T Korn Shell) e mksh (atualmente ativamente desenvolvido pdksh derivativo) está, no entanto, disponível.

<<< é uma das extensões de shell "modernas" compartilhadas entre ksh93 , mksh , GNU bash e zsh .

Seu problema específico ...

read A B C <<< $line

… pode ser trabalhado com isso (shell Korn):

print -r -- $line |&
read -p A B C

Você também pode usar este (shell POSIX), mas tem pena de desempenho tffile (por outro lado, <<< provavelmente também tem isso):

read A B C <<EOF
$line
EOF

Se você quiser apenas dividir as palavras:

set -A arrname -- $line

Em seguida, use ${arrname[0]} em vez de $A e ${arrname[1]} em vez de $B . Apenas não será interrompido a divisão em três elementos, portanto, se $line for " foo bar baz bla ", $C conterá "baz bla", enquanto ${arrname[2]} terá "baz" e ${arrname[3]} terá "bla".

Se você não precisa dos seus parâmetros posicionais, você pode fazer

set -- $line
A=$1; shift
B=$1; shift
C=$*

O shift causará erros se $line tiver menos de três palavras (verifique $# se não tiver certeza ou use [[ $line = *' '*' '[! ] ]] (provavelmente mais lento) para verificar primeiro).

Lembre-se que set … $line também fará globbing (obrigado Stéphane por nos lembrar), então você precisa de set -o noglob antes (e possivelmente restaurar o estado anterior depois, geralmente set +o noglob ).

Divulgação completa: sou o desenvolvedor mksh .

    
por 18.06.2018 / 14:35
8

Não, aqui vem strings de zsh em 2.0 em 1991 (e / ou a porta Unix de rc , seu respectivo autor trocando idéias por volta dessa época, não está claro qual dos dois teve a ideia ou incluído em sua concha primeiro).

Foi adicionado ao bash em 2.05b (2002), ksh93 em m + (2002), mksh em R33 (2008), yash em 2.7 (2009).

O ksh88 não está recebendo novos recursos.

Aqui os documentos ( << ), eles próprios vêm da Bourne-shell no final dos anos 70.

read A B C lê uma linha lógica nas variáveis A , B e C de uma maneira muito especial (um pouco menos especial com o valor padrão de $IFS que contém apenas caracteres IFS-white-space), com barras invertidas agindo como um caractere de continuação de linha e de escape e o que está acontecendo em C sendo bastante complexo também. Fazer a mesma coisa sem read seria muito difícil.

Aqui mesmo assim, <<< é o mesmo que << , com apenas diferenças sintáticas.

read A B C << EOF
$var
EOF

é exatamente o mesmo que

read A B C <<< "$var" # note that some versions of bash need the quotes

em todos os shells. Para ambos, o shell cria um arquivo temporário excluído com o conteúdo e uma nova linha adicional (embora alguns shells usem pipes em vez disso). Então read lê uma linha lógica dela (possivelmente em várias linhas físicas continuadas com contrabarra) e preenche as variáveis usando suas regras complexas.

Atribui apenas as primeiras 3 palavras (delimitadas por SPC / TAB) de $var a $A , $B e $C if

  • $IFS ainda contém seu valor padrão
  • a variável não contém barras invertidas e não há novas linhas
  • a variável contém apenas 3 palavras.

Para as três primeiras palavras, você pode fazer:

function split_into {
  typeset words IFS v i=0
  set -o noglob

  set -A words -- $1; shift
  for v do
    eval "$v=\${words[i]}"
    ((i += 1))
  done
}

split_into "$var" A B C
    
por 18.06.2018 / 14:42