我有一个像这样的字符串:
8080 "ac ac df asd" 9019 "f v adfs" 1 "123 da 123x"
有没有一种聪明的方法可以使用 Bash 将其转换为这样的数组?
8080 "ac ac df asd"
9019 "f v adfs"
1 "123 da 123x"
答案1
# 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[@]}"
输出:
“8080”“ac ac df asd” “9019”“fv adfs” “1”“123 da 123x”
答案2
我想这就是你想要的,假设可以使用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"
您正在寻找的方法是识别模式并将其替换为换行符\n
。我们识别的模式sed
是引号后跟一个空格,然后是一个数字。
" ...digit...
在这些情况下,我们想在+\n
后面添加一个"
空格。鉴于现在空格将出现在行尾,我们可以删除它,因此,"\n\1
。笔记:这是一个变量,当我们在in\1
的匹配侧执行此操作时,我们将数字保存在其中,即。当您用转义括号 包裹字符串时,您可以保存它们。s/..match../..replace../g
sed
\([0-9]\)
sed
\(..save this..\)
答案3
这会将您的值拆分为单独的数组项,然后您可以将其连接起来。我确信有更好的方法,但这会根据您提供的输入提供您所请求的输出。如果这是用户输入(或者如果它是您无法控制的输入),则不应使用以下解决方案,以防向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
此代码假定每对中的第二个需要引号(它们在 期间被删除eval
)。您也许可以通过仅在该值包含空格时在该值周围添加引号来使这一点变得更聪明,但我在这里没有这样做。