Using wildcard for files with jq on Windows
up vote
1
down vote
favorite
I am using jq 1.6 on Windows 8.1 and facing same issue as reported here
https://github.com/stedolan/jq/issues/1644
Command as simple as jq . *.json
is failing with following error:
Assertion failed!
Program: jq.exe
File: src/main.c, Line 256
Expression: wargc == argc
This application has requested the Runtime
to terminate it in an unusual way. Please contact the application's
support team for more information.
Does anyone have solution to this? What is the correct way to use jq
with all the files in the folder on windows?
windows cmd jq
add a comment |
up vote
1
down vote
favorite
I am using jq 1.6 on Windows 8.1 and facing same issue as reported here
https://github.com/stedolan/jq/issues/1644
Command as simple as jq . *.json
is failing with following error:
Assertion failed!
Program: jq.exe
File: src/main.c, Line 256
Expression: wargc == argc
This application has requested the Runtime
to terminate it in an unusual way. Please contact the application's
support team for more information.
Does anyone have solution to this? What is the correct way to use jq
with all the files in the folder on windows?
windows cmd jq
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I am using jq 1.6 on Windows 8.1 and facing same issue as reported here
https://github.com/stedolan/jq/issues/1644
Command as simple as jq . *.json
is failing with following error:
Assertion failed!
Program: jq.exe
File: src/main.c, Line 256
Expression: wargc == argc
This application has requested the Runtime
to terminate it in an unusual way. Please contact the application's
support team for more information.
Does anyone have solution to this? What is the correct way to use jq
with all the files in the folder on windows?
windows cmd jq
I am using jq 1.6 on Windows 8.1 and facing same issue as reported here
https://github.com/stedolan/jq/issues/1644
Command as simple as jq . *.json
is failing with following error:
Assertion failed!
Program: jq.exe
File: src/main.c, Line 256
Expression: wargc == argc
This application has requested the Runtime
to terminate it in an unusual way. Please contact the application's
support team for more information.
Does anyone have solution to this? What is the correct way to use jq
with all the files in the folder on windows?
windows cmd jq
windows cmd jq
asked Nov 20 at 7:02
Kamal
369115
369115
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
This is a curious problem.
As alredy answered by peak, cmd.exe
does not expand wildcards, leaving this work to the programs. And jq
does not handle wildcards (from the issues list, more later).
But this is not the full reason for this failure.
As the question points, source code fails in an assert: wargc == argc
. When reading the source code, in windows jq
tries to process the original command line with
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
trying to retrieve the equivalent to argv
and argc
but handling multibyte arguments.
As cmd
is not expanding the wildcard there will be three arguments (command line in question)
jq . *.json
^^ ^ ^....^
0 1 2
both in argv
and wargv
, so argc
and wargc
should match.
Then, why does it fail? Why argc
is different to wargc
?
Because GCC was used to compile the program.
And no, the problem is not GCC itself. The "problem" is that the argument handling in GCC runtime DOES expand the wildcard (Microsoft compiler runtime does not, but it doesn't matter as it will also not solve the problem).
That means that argc
and argv
(determined by GCC code with wildcard expansion) will contain information according to the number of files matching the wildcard while wargc
and wargv
(determined by MS code without wildcard expansion) will not.
A simple way to probe it is to have only one .json
file when trying the previous command. The assert will not fail but jq
will fail with jq: error: Could not open file *.json: Invalid argument
as it does not handle wildcards.
jq . test.json As seen in argv argc = 3
jq . *.json As seen in wargv wargc = 3
So, how to deal with it? Without modifying the jq
's source code your best option is to concatenate the list of files and pass it to jq
. References in peak's answer and in your comment should deal with the problem.
But remember that in cmd
and batch files your command lines are limited to 8191 characters. If it is not enough to deal with your problem you can try with something like (yes, a lot of lines, most of them comments and command usage)
@if (@this==@isBatch) @then /* ------------------------------------- batch code
@echo off
setlocal enableextensions disabledelayedexpansion
rem This is an hybrid batch/javascript file. The batch part will retrieve
rem the required information and start the cscript engine to execute the
rem javascript part of this file.
rem Retrieve a safe reference to current batch file
call :getCurrentFile thisFile fileName
rem Arguments to current batch file are the command line to execute later
rem Using an environment variable to avoid losing quotes when using the
rem internal Wscript argumeng handling routines
set [commandLine]=%*
if not defined [commandLine] (
echo(
echo usage: command1 ^| "%fileName%" command2
echo(
echo where:
echo command1 is a command generating a set of lines that will be
echo concatenated to pass as arguments to command2
echo(
echo command2 is the command to execute with all the lines from
echo command1 as command line arguments
echo(
echo examples:
echo(
echo dir /b ^| "%fileName%" cmd /c echo
echo dir /b *.json ^| "%fileName%" jq .
echo(
goto :eof
)
rem Execute the javascript part of this script
"%windir%system32cscript.exe" //nologo //e:JScript "%thisFile%"
goto :eof
:getCurrentFile fullPath fileName
set "%~1=%~f0"
set "%~2=%~nx0"
goto :eof
------------------------------------------------------------- end of batch code
*/@end //------------------------------------------------------ javascript code
/*
This script will read all lines from standard input and execute the
command stored by the batch code above into the [commandLine] environment
variable, passing as command lien arguments the concatenation of all lines
present in the standard input.
*/
var shell = WScript.CreateObject('WScript.Shell')
, commandLine = shell.Environment("PROCESS").Item('[commandLine]')
, stdIn = WScript.StdIn
, stdOut = WScript.StdOut
, stdErr = WScript.StdErr
, line = ''
, buffer =
;
// read the list of arguments from standard input
while ( !stdIn.AtEndOfStream ){
if (
line = stdIn.ReadLine().replace(/"/g, '')
) buffer.push( ' "' + line + '"' );
};
// concatenate all arguments
buffer = buffer.join('');
// if we don't have a command line, output what we have contatenated
// but if we have a command line, execute it, get its output and show it
// as it is possible that we are piping it to another process.
if ( commandLine ){
try {
stdOut.WriteLine(
shell.Exec( commandLine + buffer ).StdOut.ReadAll()
);
} catch ( e ){
stdErr.WriteLine( 'ERROR: Command line exec failed when running:' );
stdErr.WriteLine( '---------------------------------------------' );
stdErr.WriteLine( commandLine + buffer );
stdErr.WriteLine( '---------------------------------------------' );
};
} else {
stdOut.WriteLine( buffer );
};
Save it as a cmd
file (ex. list2args.cmd
) and use it as suggested
dir /b *.json | list2args.cmd jq .
The difference is that doing the concatenation inside the script part and starting the process using the WScript.Shell.Exec
method we can use command lines up to 32KB (the windows limit for command lines).
Great.. If I want to use multiple folders thendir /b/s
is also working with this..
– Kamal
Nov 22 at 10:11
@Kamal,cmd
parser executes several pases over the command line handling the caret escaping. Try with""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option ofjq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this errorFile Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?
– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separatecmd
instance is started to handle each side and thecmd
in the right side parse it again. We have^^^^
and^^^<
. After first parse we have^^
and^<
. After second parse^
and<
that is^<
– MC ND
Nov 28 at 8:23
add a comment |
up vote
1
down vote
As explained at https://en.wikibooks.org/wiki/Windows_Batch_Scripting
"Unlike shells of some other operating systems, the cmd.exe shell does not perform wildcard expansion"
So assuming you can't simply process the files one at a time, you'll either have to
create the list of files explicitly, or use a different shell.
For further details and suggestions, see
https://superuser.com/questions/460598/is-there-any-way-to-get-the-windows-cmd-shell-to-expand-wildcard-paths
and if you’re using Windows 10:
https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
This [superuser.com/a/460648] script works, and I can print file names withecho %expanded_list%
after running the script, but how to use output of that variable withjq
? This does not workjq empty %expanded_list%
, but gives error likeparse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you runjq empty FIRSTFILE
where FIRSTILE is the first filename produced byecho %expanded_list%
?
– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error ofThe input line is too long.
– Kamal
Nov 21 at 9:31
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
This is a curious problem.
As alredy answered by peak, cmd.exe
does not expand wildcards, leaving this work to the programs. And jq
does not handle wildcards (from the issues list, more later).
But this is not the full reason for this failure.
As the question points, source code fails in an assert: wargc == argc
. When reading the source code, in windows jq
tries to process the original command line with
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
trying to retrieve the equivalent to argv
and argc
but handling multibyte arguments.
As cmd
is not expanding the wildcard there will be three arguments (command line in question)
jq . *.json
^^ ^ ^....^
0 1 2
both in argv
and wargv
, so argc
and wargc
should match.
Then, why does it fail? Why argc
is different to wargc
?
Because GCC was used to compile the program.
And no, the problem is not GCC itself. The "problem" is that the argument handling in GCC runtime DOES expand the wildcard (Microsoft compiler runtime does not, but it doesn't matter as it will also not solve the problem).
That means that argc
and argv
(determined by GCC code with wildcard expansion) will contain information according to the number of files matching the wildcard while wargc
and wargv
(determined by MS code without wildcard expansion) will not.
A simple way to probe it is to have only one .json
file when trying the previous command. The assert will not fail but jq
will fail with jq: error: Could not open file *.json: Invalid argument
as it does not handle wildcards.
jq . test.json As seen in argv argc = 3
jq . *.json As seen in wargv wargc = 3
So, how to deal with it? Without modifying the jq
's source code your best option is to concatenate the list of files and pass it to jq
. References in peak's answer and in your comment should deal with the problem.
But remember that in cmd
and batch files your command lines are limited to 8191 characters. If it is not enough to deal with your problem you can try with something like (yes, a lot of lines, most of them comments and command usage)
@if (@this==@isBatch) @then /* ------------------------------------- batch code
@echo off
setlocal enableextensions disabledelayedexpansion
rem This is an hybrid batch/javascript file. The batch part will retrieve
rem the required information and start the cscript engine to execute the
rem javascript part of this file.
rem Retrieve a safe reference to current batch file
call :getCurrentFile thisFile fileName
rem Arguments to current batch file are the command line to execute later
rem Using an environment variable to avoid losing quotes when using the
rem internal Wscript argumeng handling routines
set [commandLine]=%*
if not defined [commandLine] (
echo(
echo usage: command1 ^| "%fileName%" command2
echo(
echo where:
echo command1 is a command generating a set of lines that will be
echo concatenated to pass as arguments to command2
echo(
echo command2 is the command to execute with all the lines from
echo command1 as command line arguments
echo(
echo examples:
echo(
echo dir /b ^| "%fileName%" cmd /c echo
echo dir /b *.json ^| "%fileName%" jq .
echo(
goto :eof
)
rem Execute the javascript part of this script
"%windir%system32cscript.exe" //nologo //e:JScript "%thisFile%"
goto :eof
:getCurrentFile fullPath fileName
set "%~1=%~f0"
set "%~2=%~nx0"
goto :eof
------------------------------------------------------------- end of batch code
*/@end //------------------------------------------------------ javascript code
/*
This script will read all lines from standard input and execute the
command stored by the batch code above into the [commandLine] environment
variable, passing as command lien arguments the concatenation of all lines
present in the standard input.
*/
var shell = WScript.CreateObject('WScript.Shell')
, commandLine = shell.Environment("PROCESS").Item('[commandLine]')
, stdIn = WScript.StdIn
, stdOut = WScript.StdOut
, stdErr = WScript.StdErr
, line = ''
, buffer =
;
// read the list of arguments from standard input
while ( !stdIn.AtEndOfStream ){
if (
line = stdIn.ReadLine().replace(/"/g, '')
) buffer.push( ' "' + line + '"' );
};
// concatenate all arguments
buffer = buffer.join('');
// if we don't have a command line, output what we have contatenated
// but if we have a command line, execute it, get its output and show it
// as it is possible that we are piping it to another process.
if ( commandLine ){
try {
stdOut.WriteLine(
shell.Exec( commandLine + buffer ).StdOut.ReadAll()
);
} catch ( e ){
stdErr.WriteLine( 'ERROR: Command line exec failed when running:' );
stdErr.WriteLine( '---------------------------------------------' );
stdErr.WriteLine( commandLine + buffer );
stdErr.WriteLine( '---------------------------------------------' );
};
} else {
stdOut.WriteLine( buffer );
};
Save it as a cmd
file (ex. list2args.cmd
) and use it as suggested
dir /b *.json | list2args.cmd jq .
The difference is that doing the concatenation inside the script part and starting the process using the WScript.Shell.Exec
method we can use command lines up to 32KB (the windows limit for command lines).
Great.. If I want to use multiple folders thendir /b/s
is also working with this..
– Kamal
Nov 22 at 10:11
@Kamal,cmd
parser executes several pases over the command line handling the caret escaping. Try with""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option ofjq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this errorFile Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?
– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separatecmd
instance is started to handle each side and thecmd
in the right side parse it again. We have^^^^
and^^^<
. After first parse we have^^
and^<
. After second parse^
and<
that is^<
– MC ND
Nov 28 at 8:23
add a comment |
up vote
2
down vote
accepted
This is a curious problem.
As alredy answered by peak, cmd.exe
does not expand wildcards, leaving this work to the programs. And jq
does not handle wildcards (from the issues list, more later).
But this is not the full reason for this failure.
As the question points, source code fails in an assert: wargc == argc
. When reading the source code, in windows jq
tries to process the original command line with
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
trying to retrieve the equivalent to argv
and argc
but handling multibyte arguments.
As cmd
is not expanding the wildcard there will be three arguments (command line in question)
jq . *.json
^^ ^ ^....^
0 1 2
both in argv
and wargv
, so argc
and wargc
should match.
Then, why does it fail? Why argc
is different to wargc
?
Because GCC was used to compile the program.
And no, the problem is not GCC itself. The "problem" is that the argument handling in GCC runtime DOES expand the wildcard (Microsoft compiler runtime does not, but it doesn't matter as it will also not solve the problem).
That means that argc
and argv
(determined by GCC code with wildcard expansion) will contain information according to the number of files matching the wildcard while wargc
and wargv
(determined by MS code without wildcard expansion) will not.
A simple way to probe it is to have only one .json
file when trying the previous command. The assert will not fail but jq
will fail with jq: error: Could not open file *.json: Invalid argument
as it does not handle wildcards.
jq . test.json As seen in argv argc = 3
jq . *.json As seen in wargv wargc = 3
So, how to deal with it? Without modifying the jq
's source code your best option is to concatenate the list of files and pass it to jq
. References in peak's answer and in your comment should deal with the problem.
But remember that in cmd
and batch files your command lines are limited to 8191 characters. If it is not enough to deal with your problem you can try with something like (yes, a lot of lines, most of them comments and command usage)
@if (@this==@isBatch) @then /* ------------------------------------- batch code
@echo off
setlocal enableextensions disabledelayedexpansion
rem This is an hybrid batch/javascript file. The batch part will retrieve
rem the required information and start the cscript engine to execute the
rem javascript part of this file.
rem Retrieve a safe reference to current batch file
call :getCurrentFile thisFile fileName
rem Arguments to current batch file are the command line to execute later
rem Using an environment variable to avoid losing quotes when using the
rem internal Wscript argumeng handling routines
set [commandLine]=%*
if not defined [commandLine] (
echo(
echo usage: command1 ^| "%fileName%" command2
echo(
echo where:
echo command1 is a command generating a set of lines that will be
echo concatenated to pass as arguments to command2
echo(
echo command2 is the command to execute with all the lines from
echo command1 as command line arguments
echo(
echo examples:
echo(
echo dir /b ^| "%fileName%" cmd /c echo
echo dir /b *.json ^| "%fileName%" jq .
echo(
goto :eof
)
rem Execute the javascript part of this script
"%windir%system32cscript.exe" //nologo //e:JScript "%thisFile%"
goto :eof
:getCurrentFile fullPath fileName
set "%~1=%~f0"
set "%~2=%~nx0"
goto :eof
------------------------------------------------------------- end of batch code
*/@end //------------------------------------------------------ javascript code
/*
This script will read all lines from standard input and execute the
command stored by the batch code above into the [commandLine] environment
variable, passing as command lien arguments the concatenation of all lines
present in the standard input.
*/
var shell = WScript.CreateObject('WScript.Shell')
, commandLine = shell.Environment("PROCESS").Item('[commandLine]')
, stdIn = WScript.StdIn
, stdOut = WScript.StdOut
, stdErr = WScript.StdErr
, line = ''
, buffer =
;
// read the list of arguments from standard input
while ( !stdIn.AtEndOfStream ){
if (
line = stdIn.ReadLine().replace(/"/g, '')
) buffer.push( ' "' + line + '"' );
};
// concatenate all arguments
buffer = buffer.join('');
// if we don't have a command line, output what we have contatenated
// but if we have a command line, execute it, get its output and show it
// as it is possible that we are piping it to another process.
if ( commandLine ){
try {
stdOut.WriteLine(
shell.Exec( commandLine + buffer ).StdOut.ReadAll()
);
} catch ( e ){
stdErr.WriteLine( 'ERROR: Command line exec failed when running:' );
stdErr.WriteLine( '---------------------------------------------' );
stdErr.WriteLine( commandLine + buffer );
stdErr.WriteLine( '---------------------------------------------' );
};
} else {
stdOut.WriteLine( buffer );
};
Save it as a cmd
file (ex. list2args.cmd
) and use it as suggested
dir /b *.json | list2args.cmd jq .
The difference is that doing the concatenation inside the script part and starting the process using the WScript.Shell.Exec
method we can use command lines up to 32KB (the windows limit for command lines).
Great.. If I want to use multiple folders thendir /b/s
is also working with this..
– Kamal
Nov 22 at 10:11
@Kamal,cmd
parser executes several pases over the command line handling the caret escaping. Try with""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option ofjq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this errorFile Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?
– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separatecmd
instance is started to handle each side and thecmd
in the right side parse it again. We have^^^^
and^^^<
. After first parse we have^^
and^<
. After second parse^
and<
that is^<
– MC ND
Nov 28 at 8:23
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
This is a curious problem.
As alredy answered by peak, cmd.exe
does not expand wildcards, leaving this work to the programs. And jq
does not handle wildcards (from the issues list, more later).
But this is not the full reason for this failure.
As the question points, source code fails in an assert: wargc == argc
. When reading the source code, in windows jq
tries to process the original command line with
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
trying to retrieve the equivalent to argv
and argc
but handling multibyte arguments.
As cmd
is not expanding the wildcard there will be three arguments (command line in question)
jq . *.json
^^ ^ ^....^
0 1 2
both in argv
and wargv
, so argc
and wargc
should match.
Then, why does it fail? Why argc
is different to wargc
?
Because GCC was used to compile the program.
And no, the problem is not GCC itself. The "problem" is that the argument handling in GCC runtime DOES expand the wildcard (Microsoft compiler runtime does not, but it doesn't matter as it will also not solve the problem).
That means that argc
and argv
(determined by GCC code with wildcard expansion) will contain information according to the number of files matching the wildcard while wargc
and wargv
(determined by MS code without wildcard expansion) will not.
A simple way to probe it is to have only one .json
file when trying the previous command. The assert will not fail but jq
will fail with jq: error: Could not open file *.json: Invalid argument
as it does not handle wildcards.
jq . test.json As seen in argv argc = 3
jq . *.json As seen in wargv wargc = 3
So, how to deal with it? Without modifying the jq
's source code your best option is to concatenate the list of files and pass it to jq
. References in peak's answer and in your comment should deal with the problem.
But remember that in cmd
and batch files your command lines are limited to 8191 characters. If it is not enough to deal with your problem you can try with something like (yes, a lot of lines, most of them comments and command usage)
@if (@this==@isBatch) @then /* ------------------------------------- batch code
@echo off
setlocal enableextensions disabledelayedexpansion
rem This is an hybrid batch/javascript file. The batch part will retrieve
rem the required information and start the cscript engine to execute the
rem javascript part of this file.
rem Retrieve a safe reference to current batch file
call :getCurrentFile thisFile fileName
rem Arguments to current batch file are the command line to execute later
rem Using an environment variable to avoid losing quotes when using the
rem internal Wscript argumeng handling routines
set [commandLine]=%*
if not defined [commandLine] (
echo(
echo usage: command1 ^| "%fileName%" command2
echo(
echo where:
echo command1 is a command generating a set of lines that will be
echo concatenated to pass as arguments to command2
echo(
echo command2 is the command to execute with all the lines from
echo command1 as command line arguments
echo(
echo examples:
echo(
echo dir /b ^| "%fileName%" cmd /c echo
echo dir /b *.json ^| "%fileName%" jq .
echo(
goto :eof
)
rem Execute the javascript part of this script
"%windir%system32cscript.exe" //nologo //e:JScript "%thisFile%"
goto :eof
:getCurrentFile fullPath fileName
set "%~1=%~f0"
set "%~2=%~nx0"
goto :eof
------------------------------------------------------------- end of batch code
*/@end //------------------------------------------------------ javascript code
/*
This script will read all lines from standard input and execute the
command stored by the batch code above into the [commandLine] environment
variable, passing as command lien arguments the concatenation of all lines
present in the standard input.
*/
var shell = WScript.CreateObject('WScript.Shell')
, commandLine = shell.Environment("PROCESS").Item('[commandLine]')
, stdIn = WScript.StdIn
, stdOut = WScript.StdOut
, stdErr = WScript.StdErr
, line = ''
, buffer =
;
// read the list of arguments from standard input
while ( !stdIn.AtEndOfStream ){
if (
line = stdIn.ReadLine().replace(/"/g, '')
) buffer.push( ' "' + line + '"' );
};
// concatenate all arguments
buffer = buffer.join('');
// if we don't have a command line, output what we have contatenated
// but if we have a command line, execute it, get its output and show it
// as it is possible that we are piping it to another process.
if ( commandLine ){
try {
stdOut.WriteLine(
shell.Exec( commandLine + buffer ).StdOut.ReadAll()
);
} catch ( e ){
stdErr.WriteLine( 'ERROR: Command line exec failed when running:' );
stdErr.WriteLine( '---------------------------------------------' );
stdErr.WriteLine( commandLine + buffer );
stdErr.WriteLine( '---------------------------------------------' );
};
} else {
stdOut.WriteLine( buffer );
};
Save it as a cmd
file (ex. list2args.cmd
) and use it as suggested
dir /b *.json | list2args.cmd jq .
The difference is that doing the concatenation inside the script part and starting the process using the WScript.Shell.Exec
method we can use command lines up to 32KB (the windows limit for command lines).
This is a curious problem.
As alredy answered by peak, cmd.exe
does not expand wildcards, leaving this work to the programs. And jq
does not handle wildcards (from the issues list, more later).
But this is not the full reason for this failure.
As the question points, source code fails in an assert: wargc == argc
. When reading the source code, in windows jq
tries to process the original command line with
wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
trying to retrieve the equivalent to argv
and argc
but handling multibyte arguments.
As cmd
is not expanding the wildcard there will be three arguments (command line in question)
jq . *.json
^^ ^ ^....^
0 1 2
both in argv
and wargv
, so argc
and wargc
should match.
Then, why does it fail? Why argc
is different to wargc
?
Because GCC was used to compile the program.
And no, the problem is not GCC itself. The "problem" is that the argument handling in GCC runtime DOES expand the wildcard (Microsoft compiler runtime does not, but it doesn't matter as it will also not solve the problem).
That means that argc
and argv
(determined by GCC code with wildcard expansion) will contain information according to the number of files matching the wildcard while wargc
and wargv
(determined by MS code without wildcard expansion) will not.
A simple way to probe it is to have only one .json
file when trying the previous command. The assert will not fail but jq
will fail with jq: error: Could not open file *.json: Invalid argument
as it does not handle wildcards.
jq . test.json As seen in argv argc = 3
jq . *.json As seen in wargv wargc = 3
So, how to deal with it? Without modifying the jq
's source code your best option is to concatenate the list of files and pass it to jq
. References in peak's answer and in your comment should deal with the problem.
But remember that in cmd
and batch files your command lines are limited to 8191 characters. If it is not enough to deal with your problem you can try with something like (yes, a lot of lines, most of them comments and command usage)
@if (@this==@isBatch) @then /* ------------------------------------- batch code
@echo off
setlocal enableextensions disabledelayedexpansion
rem This is an hybrid batch/javascript file. The batch part will retrieve
rem the required information and start the cscript engine to execute the
rem javascript part of this file.
rem Retrieve a safe reference to current batch file
call :getCurrentFile thisFile fileName
rem Arguments to current batch file are the command line to execute later
rem Using an environment variable to avoid losing quotes when using the
rem internal Wscript argumeng handling routines
set [commandLine]=%*
if not defined [commandLine] (
echo(
echo usage: command1 ^| "%fileName%" command2
echo(
echo where:
echo command1 is a command generating a set of lines that will be
echo concatenated to pass as arguments to command2
echo(
echo command2 is the command to execute with all the lines from
echo command1 as command line arguments
echo(
echo examples:
echo(
echo dir /b ^| "%fileName%" cmd /c echo
echo dir /b *.json ^| "%fileName%" jq .
echo(
goto :eof
)
rem Execute the javascript part of this script
"%windir%system32cscript.exe" //nologo //e:JScript "%thisFile%"
goto :eof
:getCurrentFile fullPath fileName
set "%~1=%~f0"
set "%~2=%~nx0"
goto :eof
------------------------------------------------------------- end of batch code
*/@end //------------------------------------------------------ javascript code
/*
This script will read all lines from standard input and execute the
command stored by the batch code above into the [commandLine] environment
variable, passing as command lien arguments the concatenation of all lines
present in the standard input.
*/
var shell = WScript.CreateObject('WScript.Shell')
, commandLine = shell.Environment("PROCESS").Item('[commandLine]')
, stdIn = WScript.StdIn
, stdOut = WScript.StdOut
, stdErr = WScript.StdErr
, line = ''
, buffer =
;
// read the list of arguments from standard input
while ( !stdIn.AtEndOfStream ){
if (
line = stdIn.ReadLine().replace(/"/g, '')
) buffer.push( ' "' + line + '"' );
};
// concatenate all arguments
buffer = buffer.join('');
// if we don't have a command line, output what we have contatenated
// but if we have a command line, execute it, get its output and show it
// as it is possible that we are piping it to another process.
if ( commandLine ){
try {
stdOut.WriteLine(
shell.Exec( commandLine + buffer ).StdOut.ReadAll()
);
} catch ( e ){
stdErr.WriteLine( 'ERROR: Command line exec failed when running:' );
stdErr.WriteLine( '---------------------------------------------' );
stdErr.WriteLine( commandLine + buffer );
stdErr.WriteLine( '---------------------------------------------' );
};
} else {
stdOut.WriteLine( buffer );
};
Save it as a cmd
file (ex. list2args.cmd
) and use it as suggested
dir /b *.json | list2args.cmd jq .
The difference is that doing the concatenation inside the script part and starting the process using the WScript.Shell.Exec
method we can use command lines up to 32KB (the windows limit for command lines).
edited Nov 20 at 21:12
answered Nov 20 at 11:13
MC ND
58.1k54777
58.1k54777
Great.. If I want to use multiple folders thendir /b/s
is also working with this..
– Kamal
Nov 22 at 10:11
@Kamal,cmd
parser executes several pases over the command line handling the caret escaping. Try with""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option ofjq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this errorFile Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?
– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separatecmd
instance is started to handle each side and thecmd
in the right side parse it again. We have^^^^
and^^^<
. After first parse we have^^
and^<
. After second parse^
and<
that is^<
– MC ND
Nov 28 at 8:23
add a comment |
Great.. If I want to use multiple folders thendir /b/s
is also working with this..
– Kamal
Nov 22 at 10:11
@Kamal,cmd
parser executes several pases over the command line handling the caret escaping. Try with""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option ofjq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this errorFile Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?
– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separatecmd
instance is started to handle each side and thecmd
in the right side parse it again. We have^^^^
and^^^<
. After first parse we have^^
and^<
. After second parse^
and<
that is^<
– MC ND
Nov 28 at 8:23
Great.. If I want to use multiple folders then
dir /b/s
is also working with this..– Kamal
Nov 22 at 10:11
Great.. If I want to use multiple folders then
dir /b/s
is also working with this..– Kamal
Nov 22 at 10:11
@Kamal,
cmd
parser executes several pases over the command line handling the caret escaping. Try with ""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
@Kamal,
cmd
parser executes several pases over the command line handling the caret escaping. Try with ""2018-05-06 11:12:13" | capture("(?^^^^^^^<Y^^^^^^^>[0-9]+)^")"
– MC ND
Nov 27 at 10:42
MD, Thanks for the reply, actually with -f option of
jq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this error File Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?– Kamal
Nov 28 at 1:29
MD, Thanks for the reply, actually with -f option of
jq
I did not face that problem(that's why I removed the comment). I tried the cmd which you shared and it does give expected output but also prints this error File Not Found
before that output. Also can you explain the reason for exact 6 extra caret signs?– Kamal
Nov 28 at 1:29
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separate
cmd
instance is started to handle each side and the cmd
in the right side parse it again. We have ^^^^
and ^^^<
. After first parse we have ^^
and ^<
. After second parse ^
and <
that is ^<
– MC ND
Nov 28 at 8:23
@Kamal, some of the carets escape the angular bracket and some escape the escape itself. Each time the line is parsed some carets are consumed as escape characters. The line is parsed when found, but as it contains a pipe a separate
cmd
instance is started to handle each side and the cmd
in the right side parse it again. We have ^^^^
and ^^^<
. After first parse we have ^^
and ^<
. After second parse ^
and <
that is ^<
– MC ND
Nov 28 at 8:23
add a comment |
up vote
1
down vote
As explained at https://en.wikibooks.org/wiki/Windows_Batch_Scripting
"Unlike shells of some other operating systems, the cmd.exe shell does not perform wildcard expansion"
So assuming you can't simply process the files one at a time, you'll either have to
create the list of files explicitly, or use a different shell.
For further details and suggestions, see
https://superuser.com/questions/460598/is-there-any-way-to-get-the-windows-cmd-shell-to-expand-wildcard-paths
and if you’re using Windows 10:
https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
This [superuser.com/a/460648] script works, and I can print file names withecho %expanded_list%
after running the script, but how to use output of that variable withjq
? This does not workjq empty %expanded_list%
, but gives error likeparse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you runjq empty FIRSTFILE
where FIRSTILE is the first filename produced byecho %expanded_list%
?
– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error ofThe input line is too long.
– Kamal
Nov 21 at 9:31
add a comment |
up vote
1
down vote
As explained at https://en.wikibooks.org/wiki/Windows_Batch_Scripting
"Unlike shells of some other operating systems, the cmd.exe shell does not perform wildcard expansion"
So assuming you can't simply process the files one at a time, you'll either have to
create the list of files explicitly, or use a different shell.
For further details and suggestions, see
https://superuser.com/questions/460598/is-there-any-way-to-get-the-windows-cmd-shell-to-expand-wildcard-paths
and if you’re using Windows 10:
https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
This [superuser.com/a/460648] script works, and I can print file names withecho %expanded_list%
after running the script, but how to use output of that variable withjq
? This does not workjq empty %expanded_list%
, but gives error likeparse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you runjq empty FIRSTFILE
where FIRSTILE is the first filename produced byecho %expanded_list%
?
– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error ofThe input line is too long.
– Kamal
Nov 21 at 9:31
add a comment |
up vote
1
down vote
up vote
1
down vote
As explained at https://en.wikibooks.org/wiki/Windows_Batch_Scripting
"Unlike shells of some other operating systems, the cmd.exe shell does not perform wildcard expansion"
So assuming you can't simply process the files one at a time, you'll either have to
create the list of files explicitly, or use a different shell.
For further details and suggestions, see
https://superuser.com/questions/460598/is-there-any-way-to-get-the-windows-cmd-shell-to-expand-wildcard-paths
and if you’re using Windows 10:
https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
As explained at https://en.wikibooks.org/wiki/Windows_Batch_Scripting
"Unlike shells of some other operating systems, the cmd.exe shell does not perform wildcard expansion"
So assuming you can't simply process the files one at a time, you'll either have to
create the list of files explicitly, or use a different shell.
For further details and suggestions, see
https://superuser.com/questions/460598/is-there-any-way-to-get-the-windows-cmd-shell-to-expand-wildcard-paths
and if you’re using Windows 10:
https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
edited Nov 20 at 17:59
answered Nov 20 at 7:47
peak
29.5k73953
29.5k73953
This [superuser.com/a/460648] script works, and I can print file names withecho %expanded_list%
after running the script, but how to use output of that variable withjq
? This does not workjq empty %expanded_list%
, but gives error likeparse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you runjq empty FIRSTFILE
where FIRSTILE is the first filename produced byecho %expanded_list%
?
– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error ofThe input line is too long.
– Kamal
Nov 21 at 9:31
add a comment |
This [superuser.com/a/460648] script works, and I can print file names withecho %expanded_list%
after running the script, but how to use output of that variable withjq
? This does not workjq empty %expanded_list%
, but gives error likeparse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you runjq empty FIRSTFILE
where FIRSTILE is the first filename produced byecho %expanded_list%
?
– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error ofThe input line is too long.
– Kamal
Nov 21 at 9:31
This [superuser.com/a/460648] script works, and I can print file names with
echo %expanded_list%
after running the script, but how to use output of that variable with jq
? This does not work jq empty %expanded_list%
, but gives error like parse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
This [superuser.com/a/460648] script works, and I can print file names with
echo %expanded_list%
after running the script, but how to use output of that variable with jq
? This does not work jq empty %expanded_list%
, but gives error like parse error: Invalid numeric literal at line 2, column 0
– Kamal
Nov 20 at 8:18
What happens when you run
jq empty FIRSTFILE
where FIRSTILE is the first filename produced by echo %expanded_list%
?– peak
Nov 20 at 21:40
What happens when you run
jq empty FIRSTFILE
where FIRSTILE is the first filename produced by echo %expanded_list%
?– peak
Nov 20 at 21:40
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
ok, I understood the problem from your comment, my folder had files other than .json, I updated the script to only return the .json files, and now it works. Thanks
– Kamal
Nov 21 at 8:24
When using in a folder containing too many files, I get error of
The input line is too long.
– Kamal
Nov 21 at 9:31
When using in a folder containing too many files, I get error of
The input line is too long.
– Kamal
Nov 21 at 9:31
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53387811%2fusing-wildcard-for-files-with-jq-on-windows%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown