remove specific character from a string with batch script - string

i want to remove only a specific character into a string and only one time. for example, if I have this file:
"1234 + test.txt"
i want to remove "+" character. my problem is that I don't know how many "+" could be in filename; by the way, I want to remove only the first:
"1234 ++ test + hello + world.txt"
need to be:
"1234 + test + hello + world.txt"
I need to do this with a bat script. I have some problems to use correctly "token,delims" parameters....
edit: I've a problem with Edoro's solution. if filename is "++plus--.txt", %left% is "plus--.txt" and %right% is +plus--.txt

pure batch
#echo off &setlocal
set "string=1234 ++ test + hello + world.txt"
for /f "delims=+" %%i in ("%string%") do set "left=%%i"
set "right=%string:*+=%"
set "new=%left%%right%"
echo %new%
..output is:
1234 + test + hello + world.txt

Go through a sed script:
echo "1234 + test + hello + world.txt" | sed 's/+//'

Related

Powershell to truncate a string

I'm trying to truncate a string which I'm fetching from an excel file.
The string(URL) is: ;#://abc.com/sites/abcx/000000103483/default.aspx;#000000103483;#
I need it to be: abc.com/sites/abcx/000000103483/
But the problem is abcx in the URL ranges from abcx to abcxxxx, where x is an integer.
How can I get the required result?
In PowerShell, you could split on /s and build the string you want like this:
$string = ";#://abc.com/sites/abcx/000000103483/default.aspx;#000000103483;#"
$split = $string.Split("/")
$split[2] + "/" + $split[3] + "/" + $split[4] + "/" + $split[5] + "/"
Output:
abc.com/sites/abcx/000000103483/
Remove default.aspx and everything that comes behind it.
$s = ';#://abc.com/sites/abcx/000000103483/default.aspx;#000000103483;#'
$s -replace 'default\.aspx.*'

Why does an empty string get enclosed within a single quotes in a shell script?

I've written a simple shell script "sample.sh" as below
#!/bin/bash
PARAM1="Parameter1"
PARAM2=\"\"
echo "param1-->[$PARAM1] - param2-->[$PARAM2]"
# sample is a compiled binary that just prints it's command line arugments.
./sample -param1 $PARAM1 -param2 $PARAM2
The script is run with -x option as
bash -x sample.sh
The output which I got is
[tspot#raspberrypi : ~/src/sample]$ bash -x sample.sh
+ PARAM1=Parameter1
+ PARAM2='""'
+ echo 'param1-->[Parameter1] - param2-->[""]'
param1-->[Parameter1] - param2-->[""]
+ ./sample -param1 Parameter1 -param2 '""'
arg[0] - [./sample]
arg[1] - [Parameter1]
arg[2] - [""]
[tspot#raspberrypi : ~/src/sample]$
My doubt is why do we get a single quote surrounding the empty string in -param2 in the below line
+ ./sample -param1 Parameter1 -param2 '""'
I would need the line to be
+ ./sample -param1 Parameter1 -param2 ""
Thanks in Advance. Someone please help me out.
That's just the way bash -x formats things in it's debug output. It's adding the extra ' ' to indicate that the string is literally "" and not an empty string. If you look a few lines below, you can see that ./sample does have the expected output: arg[2] - [""].
The problem is that your variable $PARAM2 is the string "" (literally two double quotes).
For what you want, I think you just need to initialize it with :
PARAM2=""
# Or
PARAM2=''
Both are equivalent here.
FYI, the difference between single ' and double " quotes in Bash, is that you can put variable $foo in double quotes and they will be evaluated, whereas it will show literal $ in single quotes :
$ foo=bar
$ echo ">$foo<"
>bar<
$ echo '>$foo<'
>$foo<

wget: reading from a list with id numbers and urls

In a .txt file, I have 500 lines containing an id number and a website homepage URL, in the following way
id_345 http://www.example1.com
id_367 http://www.example2.org
...
id_10452 http://www.example3.net
Using wget and the -i option, I am trying to download recursively part of these websites, but I would like to store the files in a way that is linked with the id number (storing the files in a directory called like the id number, or - the best option, but i think the most difficult to achieve - storing the html content in a single txt file called like the id number) .
Unfortunataly, the option -i cannot read a file like the one that i am using.
How can link the websites content with their connected id?
Thanks
P.s.: I imagine that to do so I have to 'go out' from wget, and call it through a script. If so, please take into account that I am a newbie in this sector (just some python experience), and that in particular I am not yet able to understand the logic and the code in bash scripts: step by step explanations for dummies are therefore very welcome.
Get site recursively with wget -P ... -r -l ... in Python, with parallel processing (gist is here):
import multiprocessing, subprocess, re
def getSiteRecursive(id, url, depth=2):
cmd = "wget -P " + id + " -r -l " + str(depth) + " " + url
subprocess.call(cmd, shell=True)
input_file = "site_list.txt"
jobs = []
max_jobs = multiprocessing.cpu_count() * 2 + 1
with open(input_file) as f:
for line in f:
id_url = re.compile("\s+").split(line)
if len(id_url) >= 2:
try:
print "Grabbing " + id_url[1] + " into " + id_url[0] + " recursively..."
if len(jobs) >= max_jobs:
jobs[0].join()
del jobs[0]
p = multiprocessing.Process(target=getSiteRecursive,args=(id_url[0],id_url[1],2,))
jobs.append(p)
p.start()
except Exception, e:
print "Error for " + id_url[1] + ": " + str(e)
pass
for j in jobs:
j.join()
Get single page into named file with Python:
import urllib2, re
input_file = "site_list.txt"
#open the site list file
with open(input_file) as f:
# loop through lines
for line in f:
# split out the id and url
id_url = re.compile("\s+").split(line)
print "Grabbing " + id_url[1] + " into " + id_url[0] + ".html..."
try:
# try to get the web page
u = urllib2.urlopen(id_url[1])
# save the GET response data to the id file (appended with "html")
localFile = open(id_url[0]+".html", 'wb+')
localFile.write(u.read())
localFile.close()
print "got " + id_url[0] + "!"
except:
print "Could not get " + id_url[0] + "!"
pass
Example site_list.txt:
id_345 http://www.stackoverflow.com
id_367 http://stats.stackexchange.com
Output:
Grabbing http://www.stackoverflow.com into id_345.html...
got id_345!
Grabbing http://stats.stackexchange.com into id_367.html...
got id_367!
Directory listing:
get_urls.py
id_345.html
id_367.html
site_list.txt
And if you prefer command line or shell scripting, you can use awk to read each line with the default splitting at spaces, pipe it to a loop and execute with the backtick:
awk '{print "wget -O " $1 ".html " $2}' site_list.txt | while read line ; do `$line` ; done
Breakdown...
awk '{print "wget -O " $1 ".html " $2}' site_list.txt |
Use the awk tool to read each line of the site_list.txt file and
split each line at spaces (default) into variables ($1, $2, $3,
etc.), so that your id is in $1 and your url is in $2.
Add the print AWK command to construct the call for wget.
Add the pipe operator | to send the output to the next command
Next we do the wget call:
while read line ; do `$line` ; done
Loop through the prior command output line by line, storing it into the $line variable, and execute it using the backtick operator to interpret the text and run it as a command

Switch statement in csh

I am trying to make a switch statement to work in tcsh but I am not sure why it is not working. I am displaying a menu on the screen and if the option is selected it shows the price and then goes back to the top and repeats until the exit option is selected.
#!/bin/csh
clear
echo -n "Petes A Pizza "
echo -n " Menu "
echo -n " "
echo -n " Make a selection "
echo -n " "
echo -n " A. Speciality Pizza "
echo -n " B. Veggi Lovers Pizza "
echo -n " C. Meat Lovers Pizza "
echo -n " D. Hawaiian Pizza "
echo -n " E. Cheese Pizza "
echo -n " F. Exit "
set a = $<
switch ($a)
case [A] :
set A = ((7.99 + 0.07))
echo $A
sleep 5
goto top
case [B] : #they choose option 2
set B = ((8.99 * 0.07) + 8.99)
echo $B
sleep 5
goto top
case [C] : #they choose option 3
set C = ((6.99 * 0.07) + 6.99)
echo $C
sleep 5
goto top
case [D] : #they choose option 4
set D = ((8.49 * 0.07) + 8.49)
echo $D
sleep 5
goto top
case [E] : #they choose option 5
set E = ((3.99 * 0.07) + 3.99)
echo $E
sleep 5
case [F] :
exit 0
breaksw
endsw
end
Here are a few suggestions that should be enough to help you get it working.
Change #!/bin/csh to #!bin/csh -f. This tells the shell not to read your ~/.cshrc file, which saves time and can avoid confusion. (If you accidentally write code that depends on aliases you've defined in your .cshrc, for example, your script won't work for anyone else.)
If you must clear the screen, the clear command is the way to do it -- but why? If I want to clear my screen before running your script, I'll do it myself, thank you very much. If I have information on my screen that I don't want to lose, I'll be annoyed when your script decides to erase it for me.
Change all the echo -ns to just echo. The -n option tells echo to print its output without a trailing newline; your entire menu will be printed on one line.
The square brackets in your case labels are unnecessary. case A : means the same thing as case [A] :. Note that you're requiring the user to provide input in upper case, which may be inconvenient.
set A = ((7.99 + 0.07))
...
set B = ((8.99 * 0.07) + 8.99)
These are inconsistent. It looks like you're trying to compute a base price plus 7% sales tax. For case B, a simpler expression for that is 8.99 * 1.07.
csh doesn't recognize this (( ... )) syntax; I wonder where you got the idea that it does. csh can do arithmetic using the # command:
# x = 2 + 2
# x ++
but it only operates on integers. The bc command can do floating-point calculations. You could write something like:
set B = `echo 'scale=5; 1.07 * 8.99' | bc`
Or, more simply:
set B = `echo '1.07 * 8.99' | bc -l
but bc -l may give you more digits than you want. man bc for more information on the bc command, its syntax, and how it works. Remember that the values of csh variables are strings, not numbers.
(I'm not sure bc is the best tool for this job.)
Finally, csh is not the best language for writing scripts. I've been using it for more years than I care to admit, and I sometimes have to resort to trial and error to find out how a given piece of syntax will behave; the syntax is poorly defined in many cases, and the man page doesn't always clear things up.
Suggested reading: "Csh Programming Considered Harmful", by Tom Christiansen.

Variable as bash array index?

#!/bin/bash
set -x
array_counter=0
array_value=1
array=(0 0 0)
for number in ${array[#]}
do
array[$array_counter]="$array_value"
array_counter=$(($array_counter + 1))
done
When running above script I get the following debug output:
+ array_counter=0
+ array_value=1
+ array=(0 0 0)
+ for number in '${array[#]}'
+ array[$array_counter]=1
+ array_counter=1
+ for number in '${array[#]}'
+ array[$array_counter]=1
+ array_counter=2
+ for number in '${array[#]}'
+ array[$array_counter]=1
+ array_counter=3
Why does the variable $array_counter not expand when used as index in array[]?
Bash seems perfectly happy with variables as array indexes:
$ array=(a b c)
$ arrayindex=2
$ echo ${array[$arrayindex]}
c
$ array[$arrayindex]=MONKEY
$ echo ${array[$arrayindex]}
MONKEY
Your example actually works.
echo ${array[#]}
confirms this.
You might try more efficient way of incrementing your index:
((array_counter++))

Resources