I'm short on time and am looking to create a very simple batch script that will:
1) Rename a string within another file in the same directory (name of file is known)
Example: Replace "[replace_me_with_path_to_second_file]" with "current_working_directory/second_file.txt" in first_file.txt
2) Open/Execute that file "first_file.txt"
3) close
Thanks in advance!
This is a perfect job for sed, if you're comfortable with regular expressions. Sed uses '/' as the delimeter between the expression to find and its replacement, so you should escape any slashes in the file path. To use your example:
sed -i 's/replace_me_with_path_to_second_file/current_working_directory\/second_file.txt/' first_file.txt
Thanks Alberge, I was hoping of finding a solution that wouldn't require sed since this batch file would be used within a downloaded file in a windows environment to simplify configuration. But looks like I'll have to package it: http://gnuwin32.sourceforge.net/packages/sed.htm
As for the rest of you, the whole premise of a collaborative question/answer directory implies that the person asking the question is either:
1) unable to find an answer
2) short on time and is looking for advice from those with more experience or knowledge in the subject matter.
Criticizing me for stating that I am asking a question because I am constrained on time is somewhat rude.
Turns out that the sed dependencies (dlls) where a little heavy so I found this useful and compact vbs script to emulate the s/r - Is there any sed like utility for cmd.exe
I'll re-post it here:
Dim pat, patparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
inp = WScript.StdIn.ReadLine()
WScript.Echo rxp.Replace(inp, patparts(2))
Loop
And my finished Batch script:
#echo off
set full_path=%CD%\file_1.txt
set input_file=file_2.txt
set output_file=file_2.txt
set str_search=FIND_ME
set str_replace=%full_path%
if not exist "%full_path%" (echo this file does not exist...)&goto :eof
cscript //nologo sed.vbs s/%str_search%/"%str_replace%"/ <%input_file% >%output_file%
Works like a charm :)
Related
I want to run the following shell command
shell:
"""
Rscript -e "rmarkdown::render('{input.markdown}', output_dir = 'output/{wildcards.version}', params = list(datapath = '../data/{wildcards.version}', max_lab_days = {config[max_lab_days]}, seed = {config[seed]}))"
"""
everything is fine in normal mode but breaks down when setting --use-singularity. I guess this is come quoting related issue since singularity exec adds another layer of quotes here, right?
So, I guess my question is how to avoid this quotation hell - any ideas?
okay, turns out the single quotes, ', are the problem - never use them in a snakemake shell command or it will not be portable to singularity execution. Fortunately one may escape them for the Rscript -e command by replacing ' with \".
Is that really necessary?
This question is probably unnecessary as I probably have been searching for the wrong criteria. It's pretty easy I think but I just can't find the answer. I use batch files to automate installs with my work, setting folder permissions, copying files here, and there, silently running programs, removing old ones etc. The batch files contain lots of repetition and I want to tidy them up greatly for easier management. I have decided to set the repeated commands and copy folder locations as variables then use them instead. This is all fine but I'm adding the variables as a LIST which looks rubbish to me, I'm sure I can load them together in a sentence rather than a new line for each. Here's what I mean...
set dir1=md c:\newfolder
set killtask=taskkill /im someprog.exe /f >nul 2>&1
set config=echo F| XCOPY %~dp0configfile3.cfg /y C:\newfolder
And on and on...
So at the minute my batch now looks like this
JOB1
%dir1%
%killtask%
%config%
What I want to be able to do is have it like this (to reduce length if batch file etc.)
JOB1
%dir1% %killtask% %config%
(summary of my comments to the question):
Check your variables! Some chars like pipe (|) or redirection (>) change how the line is interpreted. Use this syntax to correct it:
set "killtask=taskkill /im someprog.exe /f >nul 2>&1"
(note the quotes and their position)
you can call several commands with &:
echo hello&echo world.
With your complex variables this would probably fail/work in an unexpected way. Try
(%dir1%)&(%killtask%)&(%config%)
so that the redirections and pipes stay at their intended commands.
I have a number of files created by a program on our selling system that are produced in a format like the following:
CRY_SKI_14_EDI.LIS
CRY_SUM_14_EDI.LIS
THO_SKI_14_EDI.LIS
THO_LAK_14_EDI.LIS
CRY_SKI_IE_14_EDI.LIS
These files differ in numbers depending on the split of our product to different brandings. Is it possible to rename them all so that they read like the following:
CRY_SKI_14_EDI_DEMO.LIS
CRY_SUM_14_EDI_DEMO.LIS
THO_SKI_14_EDI_DEMO.LIS
THO_LAK_14_EDI_DEMO.LIS
CRY_SKI_IE_14_EDI_DEMO.LIS
I need the files to be correctly named prior to their FTP as a hardcoded file could potentially not exist due to the brand not being on sale and terminate the FTP which would prevent the other files following it from being transmitted to our FTP server.
The OpenVMS rename command is more handy (imho) than the windows or unix variants, because it can bulk change chuncks of the full file name. Such as 'name', 'type' or (sub)directory.
For example:
$ rename *.dat *.old
That's great but it will not change within the chunks (components) like the name part requested here.
For that, the classic DCL approach is a quick loop, either parsing directory output (Yuck!) or using F$SEARCH. For example:
$loop:
$ file = f$search("*EDI.LIS")
$ if file .eqs. "" then exit
$ name = f$parse(file,,,"name","syntax_only") ! grab name component from full name
$ rename/log 'file' 'name'_demo ! rename 'fills in the blanks'
$ goto loop
Personally I use PERL one-liners for this kind of work.
(and I test with -le using 'print' instead of 'rename' first. :-)
$ perl -e "for (<*edi.lis>) { $old = $_; s/_edi/_edi_demo/; rename $old,$_}"
Enjoy!
Hein
I'm working on a script that processes a folder and there is always one file in it I need to rename. The new name should be the parent directory name. How do I get this in a batch file? The full path to the dir is known.
It is not very clear how the script is supposed to become acquainted with the path in question, but the following example should at least give you an idea of how to proceed:
FOR %%D IN ("%CD%") DO SET "DirName=%%~nxD"
ECHO %DirName%
This script gets the path from the CD variable and extracts the name only from it to DirName.
You can use basename command:
FULLPATH=/the/full/path/is/known
JUSTTHENAME=$(basename "$FULLPATH")
You can use built-in bash tricks:
FULLPATH=/the/full/path/is/known
JUSTTHENAME=${FULLPATH##*/}
Explanations:
first # means 'remove the pattern from the begining'
second # means 'remove the longer possible pattern'
*/ is the pattern
Using built-in bash avoid to call an external command (i.e. basename) therefore this optimises you script. However the script is less portable.
I have a set of *.in files and a set of *.soln files with matching files names. I would like to run my program with the *.in file as input and compare the output to the ones found in the *.soln files. What would be the best way to go about this? I can think of 3 options.
Write some driver in Java to list files in the folder, run the program, and compare. This would be hard and difficult.
Write a bash script to do this. How?
Write a python script to do this?
I would go for a the bash solution. Also given that what you are doing is a test, I would always save the output of the myprogram so that if there are failures, that you always have the output to compare it to.
#!/bin/bash
for infile in *.in; do
basename=${infile%.*}
myprogram $infile > $basename.output
diff $basename.output $basename.soln
done
Adding the checking or exit statuses etc. as required by your report.
If the program exists, I suspect the bash script is the best bet.
If your soln files are named right, some kind of loop like
for file in base*.soln
do
myprogram > new_$file
diff $file new_$file
done
Of course, you can check the exit code of diff and
do various other things to create a test report . . .
That looks simplest to me . . .
Karl
This is primarily a problem that requires the use of the file-system with minimal logic. Bash isn't a bad choice for such problems. If it turns out you want to do something more complicated than just comparing for equality Python becomes a more attractive choice. Java doesn't seem like a good choice for a throwaway script such as this.
Basic bash implementation might look something like this:
cd dir_with_files
program=your_program
input_ext=".in"
compare_to_ext=".soIn"
for file in *$from_extension; do
diff <("$program" "$i") "${file:0:$((${#file}-3))}$compare_to_ext"
done
Untested.