Below is the sample program, that is generating a gwak command and executing it from scala.
Generated command is giving "invalid character in expression error"
If the same command is executed directly from macOS commandline, it works without error.
package org.mogli.pup.main
object GAwkSample {
def main(args: Array[String]): Unit = {
val text = "hello world"
val home = sys.env("HOME")
val cmnd = s"gawk -i inplace 'NR==7{print " + "\"" + text + "\"" + s"}1' ${home}/FirstEg.txt"
println(s"$cmnd")
import sys.process._
s"$cmnd" !
}
}
Output of above scala program :-
gawk -i inplace 'NR==7{print "hello world"}1' /Users/mogli/FirstEg.txt
gawk: cmd.
line:1: 'NR==7{print gawk: cmd. line:1: ^ invalid char ''' in
expression
Related
I am trying to get value from a nested JSON using json4s in scala.
The parse method works well for the string provided manually but null for the string provided from a file.
Here is the code
import org.json4s.jackson.JsonMethods.{parse, pretty}
import scala.io.Source
object ParseJson4s {
def map_fields(lines: String) = {
val testString = """{"Information":{"Context":"firstContext", "Assets":{"Asset":{"Name":"firstName"}}}}"""
val parseJSON_test = parse(testString)
val parseJSON = parse(lines)
println("Name from method " + pretty(parseJSON_test \ "Information" \ "Assets" \ "Asset" \ "Name"))
println("Name from file " + pretty(parseJSON \ "Information" \ "Assets" \ "Asset" \ "Name"))
}
def main(args: Array[String]): Unit = {
val file = Source.fromFile("testFile.txt").getLines()
file.foreach(map_fields)
}
}
and here is the test file
"""{"Information":{"Context":"firstContext", "Assets":{"Asset":{"Name":"firstName"}}}}"""
"""{"Information":{"Context":"secondContext", "Assets":{"Asset":{"Name":"secondName"}}}}"""
Output:
Name from method "firstName"
Name from file
Name from method "firstName"
Name from file
Thanks
Is """ mandadory for JSON records in your text file? I removed them and it works for me.
Results I've got in console:
Name from file "firstName"
Name from file "secondName"
Source code:
import org.json4s.jackson.JsonMethods.{parse, pretty}
import scala.io.Source
object Json4sTest {
def map_fields(lines: String) = {
val parseJSON = parse(lines)
println("Name from file " + pretty(parseJSON \ "Information" \ "Assets" \ "Asset" \ "Name"))
}
def main(args: Array[String]): Unit = {
val file = Source.fromFile("testFile.txt").getLines()
file.foreach(map_fields)
}
}
testFile.txt:
{"Information":{"Context":"firstContext", "Assets":{"Asset":{"Name":"firstName"}}}}
{"Information":{"Context":"secondContext", "Assets":{"Asset":{"Name":"secondName"}}}}
The reason why it fails is because the lines in the file are not valid JSON strings. A JSON string cannot start with triple quotes or quotes for that matter, unless it's just a simple string.
Triple quote(""") in scala is used to create multi-line strings and strings that contain quotes within them. You need to use them only when you define string literals(hard code strings) in scala.
So, remove the triple quotes from the lines in the file and it should give you proper results.
Try to parse from the file with jsoniter-scala, it will clearly report a position and a cause of the problem.
https://github.com/plokhotnyuk/jsoniter-scala
A small program that can be packed as a jar and you run it in the console like this:
scala program.jar -v --debug --file "/home/user/..."
Is there a way to get the whole command with all the parameters as a String?
object Main {
def main(args: Array[String]): Unit = {
println("???")
// should print: "scala program.jar -v --debug --file "/home/user/..."
}
}
You can't reliably get the complete command line (see this discussion) but you can get close.
object Main {
def main(args: Array[String]): Unit = {
val allargs = "scala" +: System.getProperty("sun.java.command").split(" ").tail
println(allargs.mkString(" "))
}
}
Use mkstring method of array. As argument you can place separator between array entities.
Ex: http://ideone.com/
val argss = Array("a", "b", "c --d")
println(argss.mkString(" "))
i am new at scala and i am trying to run this simple program that get input from the user and execute it in the operation system:
import scala.io._
import sys.process._
object MyCmd {
def main(args: Array[String]) = {
print("> ")
var inputString = StdIn.readLine()
while(!inputString.trim().equals("exit")) {
var proc = stringToProcess(inputString)
println( proc.!!)
print("> ")
inputString = StdIn.readLine()
}
}
}
but when i'm running it:
c:\IDE\scala\test>scala MyCmd
> dir
java.io.IOException: Cannot run program "dir": CreateProcess error=2, The
system cannot find the file specified
...
Any help will be much appreciate
sys.process.ProcessBuilder not runnig Windows cmd command.
See Executing shell commands from Scala REPL
If you need to use the cmd command, you can execute as
val proc = stringToProcess("cmd /C "+inputString)
println(proc.!!)
How to call an external process and read both of its exit code and standard out, once it finished?
Using sys.Process will result in an exception being thrown on different exit code than 0 for success.
Try this:
import sys.process._
val stdout = new StringBuilder
val stderr = new StringBuilder
val logger = ProcessLogger(stdout append _, stderr append _)
val status = "ls -al " ! logger
println(status)
println("stdout: " + stdout)
println("stderr: " + stderr)
Then you got both of them: status, stdout and stderr.
Have you looked at Process.exitValue?
Returns the exit value for the subprocess.
(I've asked this question on freenode #java and was requested to post here if I found a solution, so here goes)
Simple approach is to use sys.ProcessBuilder:
def RunExternal(executableName: String, executableDir: String) : (Int, List[String]) = {
val startExecutionTime = System.currentTimeMillis()
val pb : ProcessBuilder = new ProcessBuilder (executableName)
pb.directory(new java.io.File(executableDir))
val proc = pb.start()
proc.waitFor()
val exitCode = proc.exitValue()
val output = scala.io.Source.fromInputStream(proc.getInputStream).getLines.toList
val executionTime = System.currentTimeMillis() - startExecutionTime
logger.info(String.format(s"Process exited with exit code: ${exitCode}."))
logger.info(String.format(s"Process took ${executionTime} milliseconds."))
(exitCode, output)
}
I'm a Scala beginner and I'm writing a wrapper for invoking shell commands. Currently I'm trying to invoke shell commands with pipes from a specified directory.
To achieve this I wrote simple utility:
def runCommand(command: String, directory: File): (Int, String, String) = {
val errbuffer = new StringBuffer();
val outbuffer = new StringBuffer();
//run the command
val ret = sys.process.Process(command, directory) !
//log output and err
ProcessLogger(outbuffer append _ + "\n", outbuffer append _ + "\n");
return (ret, outbuffer.toString(), errbuffer.toString());
}
However with this utility I can't use pipes, for example:
runCommand("ps -eF | grep -i foo", new File("."));
First I thought, that pipes are shell's functionality, so I tried "/bin/sh -c ps -eF | grep -i foo", but it seems that expression from the right of the pipe was ignored.
I also tried running commands with ! syntax (sys.process._ package), but I couldn't figure out, how to call command from specified directory (without using "cd").
Could you please advice me, how to do this correctly?
Change
val ret = sys.process.Process(command, directory) !
to
val ret = sys.process.stringSeqToProcess(Seq("/bin/bash", "-c", "cd " + directory.getAbsolutePath + ";" + command))
Or you could directly use the magic provided by Scala:
import.scala.sys.process._
val ret = "ps -ef" #| "grep -i foo" !