I need to schedule a windows job to loop thru thousand of files and execute a command with the command options, the file name, and extension.
These files have an extension of *.xls in directory c:\proj. For example, one of the file is myImportantFile0001.xls, I would execute the following in powershell, manually:
PS> java.exe -classpath "C:\PROGRA~2\my1.0.2\lib/*" com.my.madsci -v --collector-url https://api.fun.my.com/ --oauth-url https://api.my.com/oauth/access --type /fileName:string/discovery:string --key /fileName:"myImportantFile0001/discovery:discovery" "C:\proj\myImportantFile0001_xls.txt"
couple of problems I've got are:
the command itself has double quotes,
the file name and extensions need to be found and converted
execute a java within powershell
So how can I loop thru the thousand of files to build a string to execute the command using powershell?
does below script helps you? i think it just strings combination.
$Commands = ls C:\Temp\*.xlsx | %{
"java.exe -classpath `"C:\PROGRA~2\my1.0.2\lib/*`" com.my.madsci -v --collector-url https://api.fun.my.com/ --oauth-url https://api.my.com/oauth/access --type /fileName:string/discovery:string --key /fileName:`"$($_.BaseName)/discovery:discovery`" `"C:\proj\$($_.BaseName)_xls.txt`""
}
$Commands
exit # remove the line if you want to execute
$Commands | %{
& $_
}
What about
PS> ls C:\Temp\*.xlsx | foreach-object {
"java.exe -classpath `"C:\PROGRA~2\my1.0.2\lib/*`" com.my.madsci -v --collector-url https://api.fun.my.com/ --oauth-url https://api.my.com/oauth/access --type /fileName:string/discovery:string --key /fileName:`"$($_.name)/discovery:discovery`" `"C:\proj\$($_.name)_xls.txt`""
}
You can do it like this:
$files = Get-ChildItem "C:\temp" -Filter "*.xls"
foreach ($file in $files)
{
$command = "java.exe -classpath ""C:\PROGRA~2\my1.0.2\lib/*"" com.my.madsci "
$command = $command + "-v --collector-url https://api.fun.my.com/ "
$command = $command + "--oauth-url https://api.my.com/oauth/access "
$command = $command + "--type /fileName:string/discovery:string "
$command = $command + ("--key /fileName:""{0}/discovery:discovery"" " -f $file.BaseName)
$command = $command + ("""C:\proj\{0}_xls.txt""" -f $file.BaseName)
Invoke-Expression $command
}
Additionally, you can also schedule it from powershell itself (Works with PS 3.0 and above)
$trigger = New-JobTrigger -Daily -At "9:00 AM"
$scriptPath = "C:\FilePath\myScript.ps1"
Register-ScheduledJob -Name "MyJob" -FilePath $scriptPath -Trigger $trigger
Related
I'm trying to execute a bcp command like below in linux using java:
bcp dbname..mytable in /home/guest/test -U guest -P guest -S LXXDB1D06 -I /opt/sybase/08/interfaces -c -Y -t \| -r \\n
In Java Class, I do as:
Runtime rt = Runtime.getRuntime();
Process p;
try {
p = rt.exec("bcp dbname..mytable in /home/guest/test -U guest -P guest -S LXXDB1D06 -I /opt/sybase/08/interfaces -c -Y -t \| -r \\n");
p.waitFor();
} catch(..){
..}
I tried with \|, "\"+"\n" and other few.
But didnt work.
What should be the correct format?
Edit: With ProcessBuilder, it looks like:
[bcp, pfactdbcpusdev01..gb_inactive_upc, in, C:\hs_data_dev_00\itm_mstr\tmp\usaupcinact_tmp_rollup, -U, inactupcUSD1, -P, inac01, -S, ACNLNXQ002D01, -I, C:\Program Files\Nielsen\Sybase\12.5.1/interfaces, -c, -t, |, -r, \n, -Y]
This is a super classical problem and I'm frankly astonished that you didn't find the solution by googling around...
The solution is to use a ProcessBuilder:
final ProcessBuilder pb = new ProcessBuilder("bcp", "dbname..mytable",
"in", "/home/guest/test",
"-U", "guest",
"-P", "guest",
"-S", "LXXDB1DO6",
"-I", "/opt/sybase/08/interfaces",
"-c",
"-Y",
"-t", "|",
"-r", "\\n"
);
final Process p = pb.start();
Also, you should check the result of .waitFor().
Also check the manpage for execve(2), execl(2) and friends.
I am trying to run bash script from java file. The script runs only the echo statement and the remaining code doesn't get executed. However, when the script is run separately, it works fine.
Java Code: Trying to run bash script from java code
Process p3 = Runtime.getRuntime().exec(chmod 777 "/path/runall_1");
String line = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(p3.getInputStream()));
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
System.out.println(output);
p3.waitFor();
Script runall_1: Compile and run C files using script
cflag="-std=gnu99 -O3"
rm -rf core
algorithm="fgme"
echo ${algorithm}
gcc ${cflag} -DAlgorithm=${algorithm} Newharness.c -lpthread -lm
Time="2"
N="32"
F="2"
rm -rf core
T="1"
while [ ${T} -le ${N} ] ; do
./a.out ${T} ${Time} ${F} # Zhang d-ary
if [ -f core ] ; then
echo core generated for ${T} ${Time} ${F}
break
fi
T=`expr ${T} + 1`
done
if [ -f core ] ; then
echo core generated for ${1}
break
fi
Output: fgme
Build Successful...
I am trying to create a shell script from java code. I am using following method to create the shell script.
String cmd = "echo -e \"echo -e abc\\\0177\\\0177\\\0177\\\0177\\\0177\\\0177\\\0177\\\0177\" > ";
String [] commands = { "/system/bin/sh", "-c", cmd + "script.sh " };
Runtime.getRuntime().exec(commands);
However, when I open the script.sh file I see following :
echo -e abc\*7\*7\*7\*7\*7\*7\*7\*7
What I want is the following:
echo -e "abc\0177\0177\0177\0177\0177\0177\0177\0177"
What is wrong with I am doing ? Any idea how to fix this ?
Not sure why you need this but you can use single quote in echo and 2 backslashes:
String cmd =
"echo -e 'echo -e abc\\\\0177\\\\0177\\\\0177\\\\0177\\\\0177\\\\0177\\\\0177\\\\0177' > ";
I am using the following Powershell script. The first half (uninstall) works flawlessly. The second half (install) only works if I allow user input. Can anyone provide some assistance? Here is the script: (sorry for poor formatting)
#uninstall
$java = Get-WmiObject -Class win32_product | where { $_.Name -like "*Java*"}
$msiexec = "C:\Windows\system32\msiexec.exe";
$msiexecargs = '/x "$($app.IdentifyingNumber)" /qn /norestart'
if ($java -ne $null)
{
foreach ($app in $java)
{
write-host $app.LocalPackage
write-host $app.IdentifyingNumber
C:\Windows\system32\cmd.exe /c "C:\Windows\system32\msiexec.exe /x $($app.IdentifyingNumber) /qn"
Start-Process -FilePath $msiexec -Arg $msiexecargs -Wait -Passthru
[Diagnostics.Process]::Start($msiexec, $msiexecargs);
}
}
if ($java -ne $null)
{
foreach ($app in $java)
{
write-host $app.LocalPackage
write-host $app.IdentifyingNumber
C:\Windows\system32\cmd.exe /c
"C:\Windows\system32\msiexec.exe /x $($app.IdentifyingNumber) /qn"
Start-Process -FilePath $msiexec -Arg $msiexecargs -Wait -Passthru
[Diagnostics.Process]::Start($msiexec, $msiexecargs);
}
}
function Get-ScriptDirectory{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
try {
Split-Path $Invocation.MyCommand.Path -ea 0
}
catch {
Write-Warning 'You need to call this function from within a saved script.'
}
}
function Get-Architecture{
return $(gwmi win32_operatingsystem).OSArchitecture
}
$Path = Get-ScriptDirectory
#Close all instances of IE, Firefox, & Chrome
Get-Process | where {$_.ProcessName -match "iexplore"} | Stop-Process -Force
Get-Process | where {$_.ProcessName -match "chrome"} | Stop-Process -Force
Get-Process | where {$_.ProcessName -match "firefox"} | Stop-Process -Force
#Install
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i "C:\temp\jre1.7.0_17.msi" ""/log "c:\temp\javainst.log " -Credential $cred -wait
#Also Install the 64-bit JRE if on a 64 workstation
if(Get-Architecture -match "64")
{
$cred = Get-Credential
Start-Process -FilePath "msiexec.exe" -ArgumentList "/i "C:\temp\jre1.7.0_17 (x64).msi" ""/log c:\temp\javainst.log " -Credential $cred -wait
}
#Import reg keys to disable auto updating
reg import "C:\temp\JavaUpdate.reg"{
}
#uninstall everything Java
Get-WmiObject -Class win32_product | ? {$_.Name -like "*Java*"} | % {msiexec /x "$($_.IdentifyingNumber)" /qn | Out-Null}
#The Out-Null waits for the command to finish
#If you have made a Java MSI use this
msiexec /i $pathtomsi /qn
#If you only have the exe you'll need to look up the Command Line Interface (CLI) for Java
$cmd = "$pathtoexe /s"
cmd /c $cmd
As for your script change the #Install line to:
Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i "C:\temp\jre1.7.0_17.msi" /log "c:\temp\javainst.log" /qn' -Credential $cred -wait
Best Practice use mostly single quotes
Last week I accidently externalized all my strings of my eclipse project. I need to revert this and my only hope is sed. I tried to create scripts but failed pathetically because I'm new with sed and this would be a very complicated operation. What I need to do is this:
Strings in class.java file is currently in the following format(method) Messages.getString(<key>). Example :
if (new File(DataSource.DEFAULT_VS_PATH).exists()) {
for (int i = 1; i <= c; i++) {
if (!new File(DataSource.DEFAULT_VS_PATH
+ Messages.getString("VSDataSource.89") + i).exists()) { //$NON-NLS-1$
getnewvfspath = DataSource.DEFAULT_VS_PATH
+ Messages.getString("VSDataSource.90") + i; //$NON-NLS-1$
break;
}
}
}
The key and matching Strings are in messages.properties file in the following format.
VSDataSource.92=No of rows in db =
VSDataSource.93=Verifying db entry :
VSDataSource.94=DB is open
VSDataSource.95=DB is closed
VSDataSource.96=Invalid db entry for
VSDataSource.97=\ removed.
key=string
So I need the java file back in this format:
if (new File(DataSource.DEFAULT_VS_PATH).exists()) {
for (int i = 1; i <= c; i++) {
if (!new File(DataSource.DEFAULT_VS_PATH
+ "String 2" + i).exists()) { //$NON-NLS-1$
getnewvfspath = DataSource.DEFAULT_VS_PATH
+ "String 1" + i; //$NON-NLS-1$
break;
}
}
}
How can I accomplish this with sed? Or is there an easier way?
This might work for you (GNU sed?):
sed 's|^\([^=]*\)=\(.*\)|s#Messages.getString("\1")#"\2"#g|;s/\\/\\\\/g' messages.properties |
sed -i -f - *.java
To repeat my comment on the question - I think that Java problems are best solved in Java :) Though this arguably is an Eclipse-helped problem caused by you :)
Make a Java program in which you can:
Read the properties,
Traverse all your project .java files,
For each file:
Read each file line by line,
Replace all the strings by using regexps, keying from the loaded properties,
Save when done reading all lines.
Not a 2-minute job, but easy enough.
But if you really want to use sed ;)
mkt.sh
$ cat mkt.sh
# Test structure
rm -rf a b
mkdir a
mkdir b
cat > a/A.java <<EOF
my plans for replace
this will be left alone
EOF
cat > b/B.java <<EOF
propery ginger
broccoli tomato potato
EOF
display() {
for i in a/A.java b/B.java; do
echo --- $i
cat $i
done
}
display
# Prop change
echo 'echo --- Replacing in: $1' > replace.sh
sed -r 's/([^=]+)=(.+)/sed -i '\''s#\1#\2#'\'' $1/' sample.properties >> replace.sh
chmod u+x replace.sh
# Replace
find -type f -name "*.java"|xargs -n1 ./replace.sh
# Test
display
Run:
$ ./mkt.sh
--- a/A.java
my plans for replace
this will be left alone
--- b/B.java
propery ginger
broccoli tomato potato
--- Replacing in: ./a/A.java
--- Replacing in: ./b/B.java
--- a/A.java
my plans for world domination
this will be left alone
--- b/B.java
propery ginger
steak tomato potato
This should work properly on your .java files, but do make a copy before ;) You will have some issues if # is in the strings, but you can solve this by removing these from properties file, doing a replace, bringing them back and changing this line:
sed -r 's/([^=]+)=(.+)/sed -i '\''s#\1#\2#'\'' $1/' sample.properties >> replace.sh
to e.g.:
sed -r 's/([^=]+)=(.+)/sed -i '\''s+\1+\2+'\'' $1/' sample.properties >> replace.sh
where + is not a remaining character. A bit of a hassle, but...
Hope this helps.
makesed.awk:
BEGIN {
FS="=";
print "for i in *.java"
print "do"
print "sed \\"
}
{
msg = "Messages.getString(\"" $1 "\")";
gsub("/","\\/",$2);
print "-e 's/" msg "/\"" $2 "\"/g' \\"
}
END {
print "$i > $$"
print "mv $$ $i"
print "done"
}
Run:
awk -f makesed.awk yourpropertiesfile.dat > process.sh
This gives you a shell script:
for i in *.java
do
sed \
-e 's/Messages.getString("VSDataSource.92")/"No of rows in db "/g' \
-e 's/Messages.getString("VSDataSource.93")/"Verifying db entry : "/g' \
-e 's/Messages.getString("VSDataSource.94")/"DB is open"/g' \
-e 's/Messages.getString("VSDataSource.95")/"DB is closed"/g' \
-e 's/Messages.getString("VSDataSource.96")/"Invalid db entry for "/g' \
-e 's/Messages.getString("VSDataSource.97")/"\ removed."/g' \
$i > $$
mv $$ $i
done
Then go in to your respective Java directories and run:
sh process.sh
That will "fix" all of the java files in that directory.
If your properties file is long, you may very well run in to a command line limit with sed. Simply split the file up in to chunks until the script is happy.
Obviously this doesn't work with any escape character, if you have "=" in your messages you'll suffer some pain as well. If you're fool enough to run this on code that isn't backed up, then you certainly deserve whatever happens to you.
But it should be a good first start.
You don't need to program anything. Right-click on one of your modified files and select "Replace With >", "Previous from Local History". Repeat as necessary.