Postgres anonymous block execution of generated dynamic sql to drop databases
You can't pass identifiers as parameters, you need to create a dynamic string. The best way to do that is to use format()

Do $$
Begin 
   execute format('drop database %I ', 'bak_20180404_2014_12'); 
End
$$ ;


You can combine that with a loop:

do
$$
declare
  l_rec record;
begin
  for l_rec in select datname from pg_database where datname like 'bak_%' 
  loop
     execute format('drop database %I ', l_rec.datname); 
  end loop;
end;
$$
;




Edit 

I always forget that you can't drop a database like that. But in psql you can easily run the result of a query as a script:

postgres=&gt; select 'drop database '||datname||';' from pg_database 
postgres-&gt; \gexec


Note the missing ; at the end of the select statement. When you terminate the query with \gexec instead of ; the query's result will be executed as a script. 

Another option is to simply spool the output to a file, so that you can inspect the drop statements before running them:

postgres=&gt; \t
Tuples only is on.
postgres=&gt; \o drop.sql
postgres=&gt; select 'drop database '||datname||';' from pg_database;
postgres=&gt; \o
postgres=&gt; \i drop.sql