Search code examples
windowsbatch-filejqoverwriteio-redirection

Output Redirection produces empty file ONLY with jq


I'm having an interesting issue. I'm using jq to minify JSON from a batch script, and I want it to replace the file it reads from. While there is probably a better solution, this, while it should work on paper, it does not work in practice.

Works:

for /R %%f in (*.json) do (
    ECHO Minifying JSON file "%%f"
    (ECHO Hello) 1> "%%f"
)

Output Files:

Hello


Shows that the redirect works

for /R %%f in (*.json) do (
    ECHO Minifying JSON file "%%f"
    ("path\to\jq" . --unbuffered --compact-output "%%f" && ECHO Hello) 1> "%%f"
)

Output Files:

Hello


Shows that jq produces output

for /R %%f in (*.json) do (
    ECHO Minifying JSON file "%%f"
    "path\to\jq" . --unbuffered --compact-output "%%f"
)

Output in CMD Window: Contents of each JSON file, minified (just like I want it)


What I'm trying to do

for /R %%f in (*.json) do (
    ECHO Minifying JSON file "%%f"
    ("path\to\jq" . --unbuffered --compact-output "%%f") 1> "%%f"
)

Output Files:

As you can see, there is no JSON present, minified or otherwise.


On the answer

@peak gave a workaround using PowerShell. In my situation, I came out with the following:

for /R %%f in (*.json) do (
    ECHO Minifying JSON file "%%f"
    powershell -Command "& {.\..\info\jq . --unbuffered --compact-output \"%%f\"|Set-Content \"%%f\"}"
)

This outputs the correct, minified JSON. What I'm doing here is invoking PowerShell to handle the minification, and using the Set-Content cmdlet.


Solution

  • Even if it works or seem to work, blindly overwriting an input file using output redirection is usually a bad idea, or worse.

    In an environment in which the (well-known) sponge utility is available, it can be used, but it looks like you might not have that luxury, so you might want to consider a more mundane approach using a temporary file.

    PowerShell users can use SetContent: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-content?view=powershell-5.1