Isto irá corresponder qualquer coisa dentro do primeiro colchete (abertura) ao primeiro colchete (fechamento) que se segue, várias vezes.
$ sed 's/[^[]*\[\([^]]*\)\][^[]*/ /g' file
foo bar
gar har
uf gc br
Descrição:
sed ' # start a sed script
s/ # start a substitute command
[^[]* # match all leading characters (except [)
\[ # match an explicit [
\([^]]*\) # capture text inside brackets.
\] # match the closing ]
[^[]* # match trailing text (if any).
/ / # replace everything matched by the captured text.
g # repeat for all the line.
' file # close script. Apply to file.
Isso adiciona um espaço à direita por correspondência. Se isso precisar ser removido, adicione uma remoção no final:
sed -e 's/[^[]*\[\([^]]*\)\][^[]*/ /g' -e 's/ $//' file
Se você tiver o grep do GNU, isso pode ajudar (uma linha por captura).
grep -Po '\[\K[^]]*(?=])'
E, se o acima não funcionar, o awk também poderá:
awk '{print gensub(/\[([^]]*)\][^[]*/,"\1 ","g")}' file