powershellsqlitenewlinecarriage-return

sqlite3 shell on Windows : extra carriage returns when using output redirection


Demonstrate the issue

Let's use nvim to create a text file:

> nvim C:\temp\in-file.txt

The contents of the text file:

> Get-Content C:\temp\in-file.txt
abc
bcd
cde

Now let's create a simple database that can store this content:

> sqlite3 C:\temp\test-1.db
-- Loading resources from C:\Users\dharm/.sqliterc
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE test_table (id INTEGER PRIMARY KEY, content TEXT NOT NULL);

Let's insert the text file content:

sqlite> INSERT INTO test_table (content) VALUES (readfile('c:\temp\in-file.txt'));
sqlite> SELECT * FROM test_table;
+----+---------+
| id | content |
+----+---------+
| 1  | abc     |
|    | bcd     |
|    | cde     |
+----+---------+

OK, looks good.

Now let's use sqlite3 to output the content to the console:

> sqlite3 C:\temp\test-1.db -cmd '.mode list' "SELECT content FROM test_table WHERE id = 1;"
-- Loading resources from C:\Users\dharm/.sqliterc
abc
bcd
cde

And now let's redirect that output to a file:

> sqlite3 C:\temp\test-1.db -cmd '.mode list' "SELECT content FROM test_table WHERE id = 1;" > C:\temp\out-5.txt
-- Loading resources from C:\Users\dharm/.sqliterc

Note that the file has extra blank lines:

> Get-Content C:\temp\out-5.txt
abc

bcd

cde


Two carriage returns per line

The Format-Hex command shows that each line has 0D 0D 0A. I.e. it has two carriage returns.

> Format-Hex C:\temp\out-5.txt

   Label: C:\temp\out-5.txt

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 61 62 63 0D 0D 0A 62 63 64 0D 0D 0A 63 64 65 0D abc���bcd���cde�
0000000000000010 0D 0A 0D 0A                                     ����

Workaround: writefile in sqlite3:

Now, I can get this to work if I use writefile in sqlite3 instead of output redirection:

> sqlite3 C:\temp\test-1.db -cmd '.mode list' "SELECT writefile('c:\temp\out-5.txt', content) FROM test_table WHERE id = 1;"
-- Loading resources from C:\Users\dharm/.sqliterc
15
> Get-Content C:\temp\out-5.txt
abc
bcd
cde

Question

Is there a way to get this to work using output redirection instead of writefile from sqlite3?

I can use the writefile approach. But I'm curious if there's a way to get the output redirection approach to work.


Solution

  • JosefZ's answer shows you how to solve the problem after the fact, on the PowerShell side - but note that the solution assumes that the stored multiline text doesn't itself contain empty lines (as they would be removed too).

    The root cause of the problem appears to be a SQLite CLI (sqlite3.exe) bug on Windows: When listing a TEXT column value containing a multiline string via sqlite3.exe, up to at least v3.50.4:

    As for the manifestations of the bug:


    Workaround:

    As an alternative to your own writefile() workaround, the simplest workaround is to ensure that multiline strings stored in your database columns use only Unix-format LF-only (\n) newlines.


    [1] Note that even PowerShell 7.4+ still exhibits this behavior when using the pipeline (rather than >) to relay output to a PowerShell-native command; this means that ... > out.txt can behave differently than ... | Set-Content out.txt.
    See this answer for more information.

    [2] See the bottom section of this answer for more information.