Writing SoX Stats to File When Running via .bat - r

Amateur coder here. I have an old R script that runs SoX stats on files across multiple folders and writes the outputs to txt files. A peer requested to use it on their Windows machine and would like to be able to just click a .bat file to run it. I made one but it outputs SoX stats to the batch file window and the txt files the stats typically output to are blank. I've read it's because of how R handles stderr but I can't find a solution for my issue. I'm really only versed in R but have been teaching myself Python, so if there's an alternative language solution like that, I'm all ears.
My "sox-stats.R" Script
setwd("~/R/sox-stats/")
for(l in list.dirs(recursive=FALSE)){
setwd(paste0("~/R/sox-stats/", l))
print(paste0("Directory set to ", l))
dir.create("./stats/", showWarnings = FALSE)
directoryAll <- list.files()
statFolder <- list.files(pattern="stats")
for(file in setdiff(directoryAll, statFolder)){
firstSox <- paste("sox \"",file,"\" -n stats",sep="")
write(system(firstSox, intern = TRUE), paste("./stats/", file, "_stats.txt", sep=""))
print(paste0(file, " has been processed."))
}
}
My .bat File
#ECHO OFF
ECHO Hello, so you want to get some SoX Stats?
ECHO ------------------------------------------------
ECHO Press any key to start me up!
PAUSE >NUL
cd C:\Program Files\R\R-3.3.0\bin
rscript sox-stats.R
IF ERRORLEVEL 1 ECHO SoX Says: Something went wrong. Check messages
above for clues. Press any key to close SoX Stats.
IF NOT ERRORLEVEL 1 ECHO SoX Says: PROCESSING COMPLETE. Press any key to close this window
and open your "sox-stats" folder.
pause >nul
IF NOT ERRORLEVEL 1 %SystemRoot%\explorer.exe "C:\Users\user\Documents\R\sox-stats"
Thanks in advance!

One way to approach this would be to use Julia, which is available for Windows. The meat of the process would be something like:
run(pipeline(`soxi mytest.wav`,"soxi.out"))
This code uses backticks to signal a console command to Julia, sets up a pipe into a named file and runs the whole thing. You could examine the contents of directories as required with a readdir() into an array of filenames and place a filter on the array as required.

Related

How to create .txt and .csv files in Unix?

I'm learning how to use the terminal and manage unix and I was wondering what is the way to make a .txt and a .csv to store some text information.
Navigate to the desired directory, e.g. cd Documents/SomeFolder
Run touch fileName.txt to create the file.
Run nano fileName.txt or vim fileName.txt to edit the file with nano or vim respectively.*
P.S. you can also skip the second step as once you exit and save the file it will automatically save it to the directory if it does not exist yet, so creating the file prior is not necessary.
*I prefer using nano as it is simple to use, once you are done editing simply press ctrl + x and it will prompt if you want to save before exiting. Vim is slightly more complex and you need to press i to enter insertion (editing) mode, then once you are done you need to press esc to exit insertion mode and then type :wq and enter to save.
echo "this is some text" > file.txt
echo "name,age,address" > file.csv
echo "Bob,37,123 Main St." >> file.csv
cat << EOF >> file.csv
Alice,34,23 Elm St.
Charlie,23,60 E. Birch Ave.
EOF

check if file is available (not in use by another process) with R

How can I check if a file is, not only existing, but not used by another process at the moment?
The context is that I am writing my output to the same file every time I run my code. The output is created with an external tool via a call to system().
When the file was opened (because I wanted to check its content) and not closed before the system() call, eveything just hangs. I would like to check that the file is available before overwriting it.
I am looking for a R solution, but I am also interested in a console (system() call) solution if it is interfaced with R. My work laptop has windows with cygwin so DOS and UNIX command are ok.
You can use the lsof from unix command line to determine which files are open at the moment:
For example:
lsof |grep test
Myprocess 1234 user 12u REG 1,4 100000 1234567 /Users/user/Folder/test.csv
Would show you if any file with the word test is being used and by what process.
This page has lots of useful examples of lsof:
http://www.thegeekstuff.com/2012/08/lsof-command-examples/
As you've mentioned, system can be used to call console commands such as lsof directly from R:
system('lsof')
You'll want to choose your directory/filename and then apply the appropriate logic as to whether the file is open:
try(amiopen <- system('lsof |grep test', intern=T))
if(is.na(amiopen[1])==T){print('Do some stuff with this file')}
To use a variable as the filename (as per this question):
myfile <- 'somefilename.txt'
try(amiopen <- system(sprintf("lsof |grep %s", myfile), intern=T))
I think you should check if R can write to the file, so check for open = "w":
file.opened <- function(path) {
suppressWarnings(
"try-error" %in% class(
try(file(path,
open = "w"),
silent = TRUE
)
)
)
}
Will return TRUE when a user has opened the file and FALSE otherwise.

Check if a file is open using Windows command line within R

I am using the shell() command to generate pdf documents from .tex files within a function. This function sometimes gets ran multiple times with adjusted data and so will overwrite the documents. Of course, if the pdf file is open when the .tex file is ran, it generates an error saying it can't run the .tex file. So I want to know whether there are any R or Windows cmd commands which will check whether a file is open or not?
I'm not claiming this as a great solution: it is hacky but maybe it will do. You can make a copy of the file and try to overwrite your original file with it. If it fails, no harm is made. If it succeeds, you'll have modified the file's info (not the contents) but since your end goal is to overwrite it anyway I doubt it will be a huge problem. In either case, you'll be fixed about whether or not the file can be rewritten.
is.writeable <- function(f) {
tmp <- tempfile()
file.copy(f, tmp)
success <- file.copy(tmp, f)
return(success)
}
openfiles /query /v|(findstr /i /c:"C:\Users\David Candy\Documents\Super.xls"&&echo File is open||echo File isn't opened)
Output
592 David Candy 1756 EXCEL.EXE C:\Users\David Candy\Documents\Super.xls
File is open
Findstr returns 0 if found and 1+ if not found or error.
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
.
--

Converting this code from R to Shell script?

So I'm running a program that works but the issue is my computer is not powerful enough to handle the task. I have a code written in R but I have access to a supercomputer that runs a Unix system (as one would expect).
The program is designed to read a .csv file and find everything with the unit ft3(monthly total) in the "Units" column and select the value in the column before it. The files are charts that list things in multiple units.
To convert this program in R:
getwd()
setwd("/Users/youruserName/Desktop")
myData= read.table("yourFileName.csv", header=T, sep=",")
funData= subset(myData, units="ft3(monthly total)", select=units:value)
write.csv(funData, file="funData.csv")
To a program in Shell Script, I tried:
pwd
cd /Users/yourusername/Desktop
touch RunThisProgram
nano RunThisProgram
(((In nano, I wrote)))
if
grep -r yourFileName.csv ft3(monthly total)
cat > funData.csv
else
cat > nofun.csv
fi
control+x (((used control x to close nano)))
chmod -x RunThisProgram
./RunThisProgram
(((It runs for a while)))
We get a funData.csv file output but that file is empty
What am I doing wrong?
It isn't actually running, because there are a couple problems with your script.
grep needs the pattern first, and quoted; -r is for recursing a
directory...
if without a then
cat is called wrong so it is actually reading from stdin.
You really only need one line:
grep -F "ft3(monthly total)" yourFileName.csv > funData.csv

Open files listed in txt

I have a list of files with their full path in a single text file. I would like to open them all at once in Windows. The file extension will tell Windows what programme to use. Can I do this straight from the command line or would I need to make a batch file? Tips on how to write the batch file appreciated.
My text file looks like the following:
J:/630/630A/SZ299_2013-04-19_19_36_52_M01240.WAV
J:/630/630A/SZ299_2013-04-19_20_15_39_M02312.WAV
J:/630/630A/SZ299_2013-04-19_21_48_07_M04876.WAV
etc
The .WAV extension is associated with Adobe Audition, which is a sound editing programme. When each path is hyperlinked in an Excel column, they can be opened with one click. Clicking on the first link will open both Audition and the hyperlinked file in it. Clicking another hyperlink will open the next file in the same instance of the programme. But this is too slow for hundreds of paths. If I open many files straight from R, e.g.
shell("J:/630/630A/SZ299_2013-04-19_19_36_52_M01240.WAV", intern=TRUE)
shell("J:/630/630A/SZ299_2013-04-19_20_15_39_M02312.WAV", intern=TRUE)
etc
each file will be opened in a new instance of the programme, which is nasty. So batch seems preferable.
for /f "delims=" %%a in (yourtextflename) do "%%a"
should do this as a batch line.
You could run this directly from the prompt if you like, but you'd need to replace each %% with % to do so.
It's a lot easier to put the code into a batch:
#echo off
setlocal
for /f "delims=" %%a in (%1) do "%%a"
then you'd just need to enter
thisbatchfilename yourtextfilename
and yourtextfilename will be substituted for %1. MUSCH easier to type - and that's what batch is all about - repetitive tasks.
Following on from this post, which uses the identify function in R to create a subset selection of rows (from a larger dataset called "testfile") by clicking on coordinates in a scatterplot. One of the columns contains the list of Windows paths to original acoustic datafiles. The last line below will open all files in the listed paths in only one instance of the programme linked to the Windows file extension.
selected_rows = with(testfile, identify(xvalue, yvalue))
SEL <-testfile[selected_rows,]
for (f in 1:nrow(SEL)){system2("open",toString(SEL[f,]$path))}

Resources