2012-07-31 4 views
13

ho una stringa dinel seguente formato:Come dividere una stringa multilinea contenente i caratteri " n" in una matrice di stringhe in bash?

I'm\nNed\nNederlander 
I'm\nLucky\nDay 
I'm\nDusty\nBottoms 

Vorrei spostare questo a un array di stringhe linea per linea in modo tale che:

$ echo "${ARRAY[0]}" 
I'm\nNed\nNederlander 

$ echo "${ARRAY[1]}" 
I'm\nLucky\nDay 

$ echo "${ARRAY[2]}" 
I'm\nDusty\nBottoms 

Tuttavia, sono incorrere in problemi con i caratteri "\ n" all'interno della stringa stessa. Sono rappresentati nella stringa come due caratteri separati, la backslash e la 'n', ma quando provo a fare lo split dell'array vengono interpretati come newline. Quindi la tipica divisione delle stringhe con IFS non funziona.

Ad esempio:

$ read -a ARRAY <<< "$STRING" 
$ echo "${#ARRAY[@]}" # print number of elements 
2 

$ echo "${ARRAY[0]}" 
I'mnNednNederla 

$ echo "${ARRAY[1]}" 
der 
+0

proposito, qualcuno sa come risolvere il problema di sE formattazione terribile del codice sopra? –

+0

La "terribile formattazione" è dovuta agli apostrofi interpretati come virgolette singole (che si aspetta siano bilanciate). Usa i tag "block quote" invece dei tag "code". – twalberg

risposta

24

Per impostazione predefinita, il comando incorporato read permette \ per sfuggire caratteri. Per disattivare questo comportamento, utilizzare l'opzione -r. Spesso non troverai un caso in cui non desideri utilizzare -r.

string="I'm\nNed\nNederlander 
I'm\nLucky\nDay 
I'm\nDusty\nBottoms" 

arr=() 
while read -r line; do 
    arr+=("$line") 
done <<< "$string" 

Per fare questo in una riga (come se stessi tentando con read -a), in realtà richiede mapfile in bash v4 o superiore:

mapfile -t arr <<< "$string" 
+0

sì per mapfile oneliner :) –

12

mapfile è più elegante, ma è possibile per fare questo in una sola riga (brutto) con read (utile se si sta utilizzando una versione di bash di età superiore a 4):

IFS=$'\n' read -d '' -r -a arr <<< "$string" 
+0

Infatti, e l'opzione -d sembra fondamentale per farlo funzionare –

+0

Un avvertimento che non sapevo quando ho postato questo: lo stato di uscita sarà diverso da zero, poiché una stringa qui non finirà mai un carattere null come 'read -d ''' si aspetterà. – chepner