How to trim/remove leading/left white spaces from a text file using Windows Batch? - postgresql

I want to remove/trim the leading/left white space which are as a result of me hiding headers and footers from my PostgreSQL query using Windows batch. I am not sure whether these are white spaces or tabs.
My SQL query:
psql -d databasename -p portname -U username -t -f filename -o "C:\text.txt"
I am not aware of any other way to do this since my SQL is a multi line query and I am not sure if we can do this using -c.
Previous the result was something like this:
After removing the header:
So as you can see there is a white space here and I want to remove it.
Can someone please help me with this?

Have a look at the -t and -A psql parameters:
-t removes headers and footers from the results
-A switches off aligned mode (which is most likely where your whitespace is coming from - alignment into columns).
So the command should look something like the following:
psql -d databasename -p portname -U username -t -A -f filename -o "C:\text.txt"
So, basically, you shouldn't need to modify the resulting file - you can modify your psql command to get results in a format you want.

Here is an hybrid script (batch\vbscript) to trim a string left and right :
#echo off
Set "VAR= abc#abc.com "
echo My Variable before the Trim Function VAR="%VAR%"
Call :Trim "%VAR%"
echo(
echo My Variable after the Trim Function VAR="%VAR%"
pause>nul & exit
::*************************************************************************
:Trim <String>
(
echo Wscript.echo Trim("%~1"^)
)>"%tmp%\%~n0.vbs"
for /f "delims=" %%a in ('Cscript /nologo "%tmp%\%~n0.vbs"') do (
set "VAR=%%a"
)
exit /b
::**************************************************************************

Related

How to export some data from Firebird database with FBExport?

I'm trying to export some data from a Firebird database, with FBExport to a CSV file.
The problem is I have two different errors. I spent a few hours to try different combinations:
Unknown switch -
Switches must begin with -
The command I tried:
fbexport -Sc -Q -F h:\AABBCC\export.csv -B -D h:\AABBCC\XXYYZZ.FDB -U "MMNNOO" -P "PPQQRR" -X "select PATIENTS.IPP, PATIENTS.NOM, PATIENTS.NOM_MARITAL, PATIENTS.NOM_USUEL, PATIENTS.PRENOMS, dmc.NUM_DOSSIER_PAPIER, dmc.NUM_DOSSIER_PAPIER_2, dmc.NUM_DOSSIER_PAPIER_3 from PATIENTS join dmc on PATIENTS.ipp = dmc.CODE where dmc.NUM_DOSSIER_PAPIER is not null or dmc.NUM_DOSSIER_PAPIER_2 is not null or dmc.NUM_DOSSIER_PAPIER_3 is not null;"
I absolutely don't understand what FBExport needs.
How can I export the data?
For me, the following command line works:
fbexport -Sc -D employee -U sysdba -P masterkey -F C:\Temp\export.csv -Q "select * from employee"
The problem in your original command was that you had a bare -Q, which caused the following -F to be interpreted as the argument of -Q, which then lead to h:\AABBCC\export.csv to be interpreted as an option, which then produced an error because it doesn't start with a -.
In addition, your command also had the following problems:
-B defines an alternative separator character for the produced CSV. It expects a separator character or TAB or \t for a tab. So, in similar vein as the previous problem, this would cause -D to be interpreted as an argument of -B, which then leads to h:\AABBCC\XXYYZZ.FDB to be interpreted as an option (without -).
-X is a primary option (like -S), to execute the query specified by -Q, instead of exporting (saving, -S). It doesn't accept a query text as argument, so the query text is also interpreted as an option (without -). This occurrence of -X should have been -Q.

looping through files for postgresql give error in windows

i'm trying to read files and load them all csv files, and once done move the files to some other location :
cd E:\data\
for /f %%a in (’dir /b filename*.CSV) do (
psql -U postgre -W password -c "COPY INTO LA from %%a" zipcodes
mv %%a E:\data\bc\
)
but it gives me following error:
E:\data>for /F %a in (ΓÇÖdir /b filename*.CSV) do (
psql -U postgre -W password-c "COPY INTO LA from %a" zipcodes
mv %a E:\data\bc\
)
The system cannot find the file ΓÇÖdir.
thanks for help
#echo off
setlocal enableextensions disabledelayedexpansion
set "psql=c:\wherever\psqlIs\psql.exe"
pushd "e:\data" && (
for %%a in ("filename*.CSV") do (
"%psql%" -U postgre -W password -c "COPY INTO LA from %%~a" zipcodes
move "%%~a" "E:\data\bc\"
)
popd
)
for /f is intended for file/string processing. To iterate over a set of files use a simple for
Anyway, the problem in your code are the opening single quote (as Alex K has pointed), the missing closing quote and the non existing mv command in windows that should be move
edited it seems there are problems with file loading. psql copy command indicates it is better to use full path names (with backslashes doubled), so
#echo off
setlocal enableextensions enabledelayedexpansion
set "psql=c:\wherever\psqlIs\psql.exe"
pushd "e:\data" && (
for %%a in ("filename*.CSV") do (
set "file=%%~fa"
"%psql%" -U postgre -W password -c "COPY INTO LA from E'!file:\=\\!'" zipcodes
move "%%~a" "E:\data\bc\"
)
popd
)

Passing value from TK to a file and replacing a variable

I am trying to interface between tk and cshell-script.
I am able to collect data using tk:
label .firstColumn.s.variable.label -text "myFirstVariable" -background $color3
entry .firstColumn.s.variable.entry -textvariable program
But when I try to run the command it does not work
button .secondColumn.o.buttons.go -text "Run Now" \
-command "exec sed -i {s/ABC/$myFirstVariable/g} runme.sh \
>! runmeNow.sh ; ./runmeNow"
It changes ABC to blank in runmeNow.sh file.
Is there any better way to achieve it?
I want to replace a place-holder predefined in cshell-script (runme.sh). My place holder is ABC. Then I want to pipe it to a different file, then run this file. runme.sh has UNIX based run file.
Seems to me that tk is interpreting $myFirstVariable as a variable of its own, while you'd like it to be forwarded to shell. Escaping the dollar sign with a backslash may not be enough: exec is a Tcl command and doesn't use a shell, so we may have to call one to expand shell variable:
button .secondColumn.o.buttons.go -text "Run Now" \
-command "exec /bin/sh -i {sed "s/ABC/$myFirstVariable/g" runme.sh \
> runmeNow.sh ; ./runmeNow.sh}"

How do I do set a variable in Windows command line to an IP?

Is there an easy way to grab the IP address from my service provider and put it into a variable via command prompt? Something like the following:
SET hostIP = nslookup \address
ECHO %hostIP%
Or
SET hostIP = ipconfig \address
ECHO %hostIP%
for /f "skip=1 tokens=2 delims=: " %f in ('nslookup %COMPUTERNAME% ^| find /i "Address"') do echo %f
The answer by Arun is good but I found that using NSLOOKUP generates a rogue comma after the hostname when more than one IP is assigned/associated with a given host.
However, I did find another way that resolves the (first assigned) IP from a given host name and doesn't generate the rogue comma - it uses PING. Very fast, very reliable.
for /f "tokens=2 delims=[]" %f in ('ping -4 -n 1 %COMPUTERNAME% ^| find /i "pinging"') do echo IP=%f
It generates a simple IPv4 address for the hostname into the variable IP. If you then do an ECHO %IP% it will show you the IP like:
IP=192.168.1.2
Of course, in batch scripts, you're going to need to replace the single %f with %%f. Note the carat ("^") in front of the pipe ("|") symbol, which is required in batch scripts so they don't interpret the pipe, and instead pipes the results of the ping statement to the find statement.
If you could use bash, (as in cygwin) this would easily be done using back-ticks to execute anything you want in your SET hostIP line.
As in
export hostIP = `curl 'http://whatsmyip.net' | grep '<title' | awk '{print $8}' | sed -e 's:<.*::g'`
Try a batch like this to set environment variables:
ipconfig > ipconfig.out
setx IPADDR /f ipconfig.out /a 7,13
setx IPADDR /f ipconfig.out /a 7,14
setx IPMASK /f ipconfig.out /a 8,14
Exit the command prompt and open a new one. Use SET and look for IPADDR and IPMASK, which are now persistent. To update the variables, you would have to rerun the batch and exit the command prompt. The different coordinates shown account for differences in the IPCONFIG output for Windows 2003 vs Windows 2008 (should work on XP/7 in the same way). Only a found value is written, so the line that fails does no harm as long as nothing is found. Add the gateway with:
setx IPGATE /f ipconfig.out /a 9,12

PostgreSQL: How to pass parameters from command line?

I have a somewhat detailed query in a script that uses ? placeholders. I wanted to test this same query directly from the psql command line (outside the script). I want to avoid going in and replacing all the ? with actual values, instead I'd like to pass the arguments after the query.
Example:
SELECT *
FROM foobar
WHERE foo = ?
AND bar = ?
OR baz = ? ;
Looking for something like:
%> {select * from foobar where foo=? and bar=? or baz=? , 'foo','bar','baz' };
You can use the -v option e.g:
$ psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'"
and then refer to the variables in SQL as :v1, :v2 etc:
select * from table_1 where id = :v1;
Please pay attention to how we pass string/date values using two quotes " '...' " But this way of interpolation is prone to SQL injections, because it's you who's responsible for quoting. E.g. need to include a single quote? -v v2="'don''t do this'".
A better/safer way is to let PostgreSQL handle it:
$ psql -c 'create table t (a int, b varchar, c date)'
$ echo "insert into t (a, b, c) values (:'v1', :'v2', :'v3')" \
| psql -v v1=1 -v v2="don't do this" -v v3=2022-01-01
Found out in PostgreSQL, you can PREPARE statements just like you can in a scripting language. Unfortunately, you still can't use ?, but you can use $n notation.
Using the above example:
PREPARE foo(text,text,text) AS
SELECT *
FROM foobar
WHERE foo = $1
AND bar = $2
OR baz = $3 ;
EXECUTE foo('foo','bar','baz');
DEALLOCATE foo;
In psql there is a mechanism via the
\set name val
command, which is supposed to be tied to the -v name=val command-line option. Quoting is painful, In most cases it is easier to put the whole query meat inside a shell here-document.
Edit
oops, I should have said -v instead of -P (which is for formatting options) previous reply got it right.
You can also pass-in the parameters at the psql command-line, or from a batch file. The first statements gather necessary details for connecting to your database.
The final prompt asks for the constraint values, which will be used in the WHERE column IN() clause. Remember to single-quote if strings, and separate by comma:
#echo off
echo "Test for Passing Params to PGSQL"
SET server=localhost
SET /P server="Server [%server%]: "
SET database=amedatamodel
SET /P database="Database [%database%]: "
SET port=5432
SET /P port="Port [%port%]: "
SET username=postgres
SET /P username="Username [%username%]: "
SET /P bunos="Enter multiple constraint values for IN clause [%constraints%]: "
ECHO you typed %constraints%
PAUSE
REM pause
"C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h %server% -U %username% -d %database% -p %port% -e -v v1=%constraints% -f test.sql
Now in your SQL code file, add the v1 token within your WHERE clause, or anywhere else in the SQL. Note that the tokens can also be used in an open SQL statement, not just in a file. Save this as test.sql:
SELECT * FROM myTable
WHERE NOT someColumn IN (:v1);
In Windows, save the whole file as a DOS BATch file (.bat), save the test.sql in the same directory, and launch the batch file.
Thanks for Dave Page, of EnterpriseDB, for the original prompted script.
I would like to offer another answer inspired by #malcook's comment (using bash).
This option may work for you if you need to use shell variables within your query when using the -c flag. Specifically, I wanted to get the count of a table, whose name was a shell variable (which you can't pass directly when using -c).
Assume you have your shell variable
$TABLE_NAME='users'
Then you can get the results of that by using
psql -q -A -t -d databasename -c <<< echo "select count(*) from $TABLE_NAME;"
(the -q -A -t is just to print out the resulting number without additional formatting)
I will note that the echo in the here-string (the <<< operator) may not be necessary, I originally thought the quotes by themselves would be fine, maybe someone can clarify the reason for this.
It would appear that what you ask can't be done directly from the command line. You'll either have to use a user-defined function in plpgsql or call the query from a scripting language (and the latter approach makes it a bit easier to avoid SQL injection).
I've ended up using a better version of #vol7ron answer:
DO $$
BEGIN
IF NOT EXISTS(SELECT 1 FROM pg_prepared_statements WHERE name = 'foo') THEN
PREPARE foo(text,text,text) AS
SELECT *
FROM foobar
WHERE foo = $1
AND bar = $2
OR baz = $3;
END IF;
END$$;
EXECUTE foo('foo','bar','baz');
This way you can always execute it in this order (the query prepared only if it does not prepared yet), repeat the execution and get the result from the last query.