teclado scripts script programacion pasar parametros latinoamericano invertidas invertida espaƱol ejemplos comillas comilla comandos bash sed awk

bash - scripts - Divida una cadena(almacenada en una variable) en varias palabras usando espacios pero no los espacios entre comillas dobles



scripts bash ejemplos (5)

Aquí hay una pequeña secuencia de comandos de Python para analizar csv delimitado por espacios respetando los campos entre comillas:

$ python -c '' import csv, fileinput for line in csv.reader(fileinput.input(), delimiter=" "): for word in line: print word '' test.csv 2012 2013 multiple words

Como esto usa el módulo fileinput, también funciona en una tubería (o una cadena en una variable):

$ str=''2012 2013 "multiple words"'' $ echo $str | python -c '' import csv, fileinput for line in csv.reader(fileinput.input(), delimiter=" "): for word in line: print word '' 2012 2013 multiple words

Estoy tratando de escribir un guión complicado, para mí, donde mi objetivo es hacer lo siguiente. Tengo una cuerda que se ve así:

2012 2013 "multiple words"

Mi objetivo es colocar cada uno de estos en una matriz dividida por espacios, pero solo para las coincidencias de una sola palabra, no para las que aparecen entre comillas dobles. Esos deben ser considerados una sola palabra. Así que mi idea era hacer esto en dos pasos. Primero haga coincidir aquellas palabras que son múltiplos, elimine esas de la cadena, luego en otra iteración dividida por espacio en blanco.
Desafortunadamente no puedo encontrar ayuda sobre cómo hacer echo del partido solamente. Hasta ahora tengo esto:

array=$(echo $tags | sed -nE ''s/"(.+)"//1/p'')

Pero esto resultaría en (en OS X):

2012 2013 multiple words

Resultado Esperado:

array[1]="2012" array[2]="2013" array[3]="multiple words"

¿Cómo me ocuparía de este tipo de problema?

Gracias.


Lo siguiente producirá el resultado que desea:

tags=''2012 2013 "multiple words"'' IFS=$''/n''; array=($(echo $tags | egrep -o ''"[^"]*"|/S+''))

resultado en ZSH:

echo ${array[1]} # 2012 echo ${array[2]} # 2013 echo ${array[3]} # "multiple words"

resultado en BASH:

echo ${array[0]} # 2012 echo ${array[1]} # 2013 echo ${array[2]} # "multiple words"

Funciona en OSX.


Usted puede hacer directamente:

arr=(2012 2013 "multiple words") echo ${#arr[@]} # gives 3 echo ${arr[2]} # gives "multiple words"

EDITAR: No estoy seguro de si ayuda al OP pero los siguientes también funcionarán

str=''2012 2013 "multiple/ words"'' read -a arr <<< $str echo ${#arr[@]} # gives 3 echo ${arr[2]} # gives "multiple words"


eval es malvado, pero este puede ser uno de esos casos en los que es útil

str=''2012 2013 "multiple words"'' eval x=($str) echo ${x[2]} multiple words

O con versiones más recientes de bash (probado en 4.3)

s=''2012 2013 "multiple words"'' declare -a ''a=(''"$s"'')'' printf "%s/n" "${a[@]}" 2012 2013 multiple words


$ grep -Eo ''"[^"]*"|[^" ]*'' <<< ''2012 2013 "multiple words"'' 2012 2013 "multiple words"

Es decir, imprimir solo las cadenas que coincidan

  1. una cita seguida de cualquier número (incluso cero) sin comillas seguido de una cita o
  2. una serie de caracteres que no contienen una cita o espacio.

Por supuesto, esto no maneja casos complicados como citas que abarcan varias líneas o citas escapadas (usando comillas dobles como SQL o barra invertida como el shell).