O AWK está lançando um erro "newline inesperado ou fim da string"

0

Meu script de bash:

declare -a lang=('english' 'spainsh')
sms="Free msg: Due to upgrades on apps you’ll need a new version by yyyy/mm/dd to app running. Visit a store or go to"
    url="google.com/UA2392 to upgrade your app." 

awk '{print $1 "," '${servicegrade[0]}' "," '${lang[1]}' ",,," '$sms' "," '$url'}' inputfile.csv > inputfile.txt

ERRO:

awk: cmd. line:1: {print $1 "," 267 "," en ",,," Free
awk: cmd. line:1:                                    ^ unexpected newline or end of string
    
por user_tmo 28.04.2015 / 23:34

1 resposta

4

O problema que você está vendo está diretamente relacionado à maneira como você está citando (ou mais precisamente, não citando) sua linha de comando awk e as variáveis de shell interpoladas. (Tanto para o shell como para awk .)

Você tem isso:

awk '{print $1 "," '${servicegrade[0]}' "," '${lang[1]}' ",,," '$sms' "," '$url'}' inputfile.csv > inputfile.txt

Empiricamente, vejo a mensagem de erro de que servicegrade=267 , lang=en , sms=Free msg:... , mas url não está visível (ok), por isso assumimos url=http://example.net .

A parte importante é olhar para suas citações na linha commnd. Qualquer coisa dentro das 'aspas simples' é tratada como uma única linha de comando. Se você se limitar a uma aspa simples contra uma aspa dupla, você também está ok ( echo 'hello'"world" tem um único argumento). Mas assim que você introduz um espaço sem aspas, ele se torna um segundo parâmetro ( echo 'hello' "world" é duas palavras, não uma). Além disso, nenhuma de suas variáveis é citada, portanto, qualquer espaço em branco em seus valores será tratado pelo shell como uma quebra de palavra.

Vamos supor que essas variáveis não contenham espaços em branco e interpole-as na linha de comando, como se fossem valores reais em vez de variáveis:

awk '{print $1 "," '267' "," 'en' ",,," 'Free msg:...' "," 'http://example.net'}' inputfile.csv > inputfile.txt

Agora vamos remover aspas redundantes:

awk '{print $1 "," 267 "," en ",,," Free msg:..."," http://example.net}' inputfile.csv > inputfile.txt

Não deve demorar mais do que um momento para perceber que awk agora está vendo strings não citadas, que ele não pode exibir como awk variables. Eu suspeito que o que você realmente queria era isso:

awk '{print $1 ",267,en,,,Free msg:...,http://example.net"}' inputfile.csv > inputfile.txt

(possivelmente com argumentos de aspas duplas, se sua saída também for estilo CSV).

Podemos reverter o processo com facilidade suficiente para permitir que as variáveis do shell sejam interpoladas, mas uma abordagem melhor é atribuir essas variáveis do shell a awk variables e usá-las:

awk '{print $1 "," servicegrade "," lang ",,," sms "," url}' servicegrade="${servicegrade[0]}" lang="${lang[1]}" sms="$sms" url="$url" inputfile.csv > inputfile.txt

Se você decidir que seu texto de saída precisa de parâmetros com aspas duplas, awk (bem, pelo menos minha versão dele) entende esse tipo de estrutura: awk '{print $1 "\"" servicegrade "\",\"" lang "\",\"" sms "\",\"" url "\""}'

    
por 29.04.2015 / 00:45

Tags