I've got a string like this:
8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
Is there a clever way to convert this into arrays like this using Bash?
8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
I've got a string like this:
8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
Is there a clever way to convert this into arrays like this using Bash?
8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
# define function foo() { while [ -n "$2" ]; do array+=( "\"$1\" \"$2\"" ); shift 2; done; } # call function with string foo 8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x" # print array printf "%s\n" "${array[@]}"
Output:
"8080" "ac ac df asd" "9019" "f v adfs" "1" "123 da 123x"
I think this is what you want, assuming it's OK to use sed
.
$ echo '8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"' | sed 's/" \([0-9]\)/"\n\1/g' 8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
The approach you're looking for is to recognize a pattern and replace it with a newline character, \n
. The pattern that we're recognizing with sed
is an quote followed by a space, followed by a digit.
" ...digit...
In those situations we want to put a \n
after the "
+ space. Given the space will now occur at the end of the line, we can drop it, hence this, "\n\1
. NOTE: The \1
is a variable that we saved the digit in when we did this on the matching side in our s/..match../..replace../g
in sed
, i.e. \([0-9]\)
. You can save pieces of strings in sed
when you wrap them with escaped parens, \(..save this..\)
.
This will split your values into separate array items, which you can then join. I'm sure there's a better way but this delivers the output you've requested from the input you've provided. If this is user input (or if it's input outside your control) the following solution should not be used in case backticks or variable substitutions are offered to the eval
.
s='8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"' eval t=("$s") # Incautious array assignment a=() for k in $(seq 0 $(( (${#t[@]}+1) /2 -1 )) ) # Count pairs of elements do p1=$((k*2)) p2=$((k*2 +1)) # Indexes into original list a+=("${t[$p1]} \"${t[$p2]}\"") # New element is a pair of originals done for p in "${a[@]}" # Report elements of array a[] do echo "item> $p" >&2 done
This code assumes that the second of each pair requires quotes (they are removed during the eval
). You could perhaps make that more clever by adding quotes around a value only if that value contained whitespace, but I haven't done that here.
1 "123 da 123x"
.