Вы видите различие с declare -p
:
unset foo
declare -a foo
declare -p foo
# prints declare -a foo='()'
foo=
declare -p foo
# prints declare -a foo='([0]="")'
Если Вы хотите инициализировать пустой массив, вывод первого declare -p
хорошая подсказка на лучшем способе объявить это:
declare -a array='()'
( declare -a
часть является, вероятно, дополнительной, простое array=()
должен работать точно также.)
Если Вы хотите протестировать, если массив имеет 0 элементов, используйте числовое сравнение на ${#array[@]}
; не пытайтесь сделать a test -z
на расширении, как не даст корректный результат во многих случаях.
Вот другой подход:
sed -e '/^[[:space:]]*bucket.*endy$/s/bucket/(bucket/' file.txt
Начальная буква /pattern/
говорит sed только работать над строками, содержащими это pattern
, и остальная часть его является простой, стандартной заменой.
Можно использовать обратные ссылки (например, \1
) в Вашем заменяющем термине, который заменит подвыражения (вещи, включенные в завершенных круглых скобках — \(…\)
) в Вашем критерии поиска. Например,
$ cat test001.txt | sed -e 's/^\([[:space:]]*\)\(bucket.*endy\)$/\1(\2/'
this
is a
test bucket
bucket line not this one.
(bucket lein endy
(bucket and others endy
and
a ttest
создаст два подвыражения:
^\([[:space:]]*\)
\(bucket.*endy\)$
Это затем заменит любую строку, которая соответствует \1(\2
, который является пробелом, сопровождаемым вводной круглой скобкой, сопровождаемой блоком.. строка endy.
\s
не часть BRE, который sed
использование. В BRE \s
совпадает с литералом s
. Эквивалент \s
был бы [[:space:]]
. Попробуйте следующее:
sed -i 's/^[[:space:]]*bucket/(bucket/g' test001.txt