J'essaie d'écrire un script compliqué pour moi dont le but est de faire ce qui suit. J'ai une ficelle qui ressemble à ceci:
2012 2013 "multiple words"
Mon objectif est de placer chacun de ceux-ci sur un tableau divisé en espaces, mais uniquement pour les correspondances Word simples, pas celles entourées de guillemets. Ceux-ci devraient être considérés comme un mot. Donc, mon idée était de faire cela en deux étapes. Commencez par faire correspondre les mots qui sont des multiples, supprimez ceux de la chaîne, puis dans une autre itération divisée par des espaces.
Malheureusement, je ne trouve aucune aide sur la façon de echo
la correspondance uniquement. Jusqu'ici j'ai ceci:
array=$(echo $tags | sed -nE 's/"(.+)"/\1/p')
Mais cela se traduirait par (sous OS X):
2012 2013 multiple words
Résultat attendu:
array[1]="2012"
array[2]="2013"
array[3]="multiple words"
Comment pourrais-je résoudre ce type de problème?
Merci.
eval
est diabolique, mais cela peut être l’un des cas où cela est utile
str='2012 2013 "multiple words"'
eval x=($str)
echo ${x[2]}
multiple words
Ou avec des versions plus récentes de bash
(testé sur la version 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"
C'est-à-dire, print only les chaînes correspondantes
Bien sûr, cela not gère les cas compliqués tels que les guillemets couvrant plusieurs lignes ou les guillemets (en utilisant des guillemets doubles comme SQL ou une barre oblique inverse comme le shell).
Vous pouvez directement faire:
arr=(2012 2013 "multiple words")
echo ${#arr[@]} # gives 3
echo ${arr[2]} # gives "multiple words"
EDIT: Je ne suis pas sûr que cela aide l'OP, mais cela fonctionnera également
str='2012 2013 "multiple\ words"'
read -a arr <<< $str
echo ${#arr[@]} # gives 3
echo ${arr[2]} # gives "multiple words"
Ce qui suit produira le résultat souhaité:
tags='2012 2013 "multiple words"'
IFS=$'\n'; array=($(echo $tags | egrep -o '"[^"]*"|\S+'))
résultat en ZSH:
echo ${array[1]} # 2012
echo ${array[2]} # 2013
echo ${array[3]} # "multiple words"
résultat en BASH:
echo ${array[0]} # 2012
echo ${array[1]} # 2013
echo ${array[2]} # "multiple words"
fonctionne sous OSX.
Voici un petit script Python pour analyser les fichiers csv délimités par des espaces tout en respectant les champs cités:
$ 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
Puisqu'il utilise le module fileinput, fonctionne dans un pipeline (ou une chaîne dans une 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