shell - Insert a character at different indexes in a string - unix

It will eventually be part of a larger script so it needs to be shell scripted. A simple task in other languages, but I'm having trouble accomplishing it in shell. Basically I have a string and I want to insert a "." at all possible indices within the string. The output can be on newlined or separated by spaces. Can anyone help?
Example:
input: "abcd"
output: ".abcd
a.bcd
ab.cd
abc.d
abcd."
OR
output: ".abcd a.bcd ab.cd abc.d abcd."

A simple for loop would do:
input=abcd
for ((i=0; i<${#input}+1; i++))
do
echo ${input::$i}.${input:$i}
done
This just slices up the string at each index and inserts a .. You can change the echo to something else like appending to an array if you want to store them instead ouf output them, of course.

Related

Is there a way to split a string into an array with space(" ") separated values in ZSH?

I have this code:
carp="2 hello 192.180.00.00"
array=( ${carp} )
echo "\n${array[2]}"
and I am trying to split carp into an array named array. my output should be "hello", but it just prints blank. Is there a simple way to split carp into an array?
zsh has a parameter expansion syntax for that: ${=spec}. To modify your example, it would be:
carp="2 hello 192.180.00.00"
array=( ${=carp} )
echo "\n${array[2]}"
The description is:
Perform word splitting using the rules for SH_WORD_SPLIT during the evaluation of spec, but regardless of whether the parameter appears in double quotes; if the ‘=’ is doubled, turn it off. This forces parameter expansions to be split into separate words before substitution, using IFS as a delimiter. This is done by default in most other shells.

Simplest way to create filename with date and time in command line or batch file

I need to append date/time to some test log files generated multiple times in a day. Some suggest doing it like:
set CUR_YYYY=%date:~10,4%
set CUR_MM=%date:~4,2%
set CUR_DD=%date:~7,2%
set CUR_NN=%time:~3,2%
set CUR_SS=%time:~6,2%
set CUR_MS=%time:~9,2%
set SUBFILENAME=%CUR_YYYY%%CUR_MM%%CUR_DD%-%CUR_HH%%CUR_NN%%CUR_SS%
And then concatenate them together but I feel it's just not right. I wonder if there is a better or more concise way of doing it? I imagine there would be a simple solution because the need is quite common.
Thanks!
Well, first of all, data/time formatting is actually a big thing in any programming languages. Just look at the long list of ToString() methods in C# DateTime class, for example, will give you an idea what it is like.
For your particular task, assuming that your locale date using "-" and your locale time using ":" as separators (you can echo date/time to verify:)
echo %date% %time%
If you are not picky, the simplest way to generate a file name is below, and you may replace the '-' and ':' characters according to your own locale, which will give you a valid file name in most systems.
echo "testResult_%date:-=%_%time::=%.xml"
"testResult_20220409_ 84841.28.xml"
If you want only alphanumeric characters in your naming, then probably a cleaner set of commands:
set shortTime=%time:~0,8% ##eliminate the milliseconds in time string
set shortTime=%shortTime: =0% ##replace empty space with zero in morning hours
echo testResult_%date:-=%_%shortTime::=%.xml ##replace '-' and ':' with nothing
That should give you something like
testResult_20220409_084841.xml
However, if you need to deal with application globalization, it's always best to format date/time to a predefined string format using something like PowerShell (on Windows) as the first step. It will then make any subsequent string manipulations easier.
powershell get-date -format "{dd-MM-yyyy_HH:mm:ss}"
When dealing with timestamps you can retrieve the date as I show here on this demo shell file (using bash):
#!/bin/bash
#gets the current timestamp
current_time=$(date "+%Y%m%d-%H%M%S")
echo "Current Time : $current_time"
#crafts the new filename appending $current_time to the original filename
original_filename="filename.log"
new_fileName=$original_filename.$current_time
echo "New FileName: " "$new_fileName"
#renames the file
#mv $original_filename $new_fileName

keep the leading zeros when echo'ing a string to a variable

I'm trying to keep the leading zeros on a number when I echo it to a csv file but I cannot find a way w/o echoing it with a single quote. How can I do this using a bash script?
After going through a file and extracting what I want and storing it in a variable, I echo it to a variable that's mapped to a file.
file name:
TMP_RESULT_STORE="/tmp/AdvertisedTotals_GLB_`date +%y%m%d`.csv"
Lets say:
SYM=0090498
Later SYM value can change to:
SYM=034249822
SYM=BVZ342
When loop through a file with a for loop and echo the SYM to a File like this:
echo $SYM >> $TMP_RESULT_STORE
The output would looks like this for the above entries:
90498
34249822
BVZ342
The leading zeros are lost. I can get it to keep the zeros like this:
echo ""\'$SYM" >> $TMP_RESULT_STORE
But then it looks like this and I cannot get rid of the single quote(pls ignore the backward single quotes at the end. I was trying to get this site to write each entry to a new line and this was the best I can do):
'0090498
'034249822
'BVZ342```
Obviously, I'm doing other stuff in this script while scraping a log, I wanted to keep it simple to understand and just focus on the issue.
How can I get the bash script to keep the leading zeros when there is or are leading zeros using bash script?

How do I concatenate strings in arduino?

sorry I am a bit rusty here, how do I concatenate these 2 outputs?
display.println(timeinfo->tm_hour);
display.println(timeinfo->tm_min);
If you just want them to appear in the output one after another on the same line then use print instead of println for the first one. Println adds a newline to the end of the output and print doesn't. It's always good to look stuff like that up before using a function.
If you really want them put together into one string then you will have to show where those strings are coming from. If they are String class objects you can just use + to put them together. If they are proper c-style strings then you will need to use strcat.
How are defining them?
If you have initialized as arrays of characters:
Example: char exampleCString[50] = "This is a C string";
Then you can use strcat() function in C:
strcat(str1,str2);
Note: Make sure "str1" buffer is big enough, because the result goes there.
If on the other hand, you have initialized your strings as objects of String class:
Example: String exampleJavaString="This is a Java String example"
Then just use the + operator to add them:
str1=str1+str2:

Decrypt many PDFs in one go using pdftk

I have 10 PDFs that ask for a user password to open. I know that password. I want to keep them in a decrypted format. Their filenames follow the form:
static_part.dynamic_part_like_date.pdf
I want to convert all the 10 files. I can give a * after the static part and work on all of them, but I also want the corresponding output filenames. So there has to be a way to capture the dynamic part of the filename and then use it in the output filename.
The normal way of doing this for one file is:
pdftk secured.pdf input_pw foopass output unsecured.pdf
I want to do something like:
pdftk var=secured*.pdf input_pw foopass output unsecured+var.pdf
Thanks.
Your request is a little ambiguous, but here are some ideas that might help you.
Assuming 1 of your 10 files is
# static_part.dynamic_part_like_date.pdf
# SalesReport.20110416.pdf (YYYYMMDD)
And you want only the SalesReport.pdf converted as unsecured, you can use a shell script to achieve your requirement:
# make a file with the following contents,
# then make it executable with `chmod 755 pdfFixer.sh`
# the .../bin/bash has to be the first line the file.
$ cat pdfFixer.sh
#!/bin/bash
# call the script like $ pdfFixer.sh staticPart.*.pdf
# ( not '$' char in your command, that is the cmd-line prompt in this example,
# yours may look different )
# use a variable to hold the password you want to use
pw=foopass
for file in ${#} ; do
# %%.* strips off everything after the first '.' char
unsecuredName=${file%%.*}.pdf
#your example : pdftk secured.pdf input_pw foopass output unsecured.pdf
#converts to
pdftk ${file} input_pw ${foopass} output ${unsecuredName}.pdf
done
You may find that you need to modify the %.* thing to
strip less from end, (use %.*) to strip just the last '.' and all chars after (strip from right).
strip from the fron (use #*.) to just the static part, leaving the dynamic part OR
strip from the front (use ##*.) to strip everything until the last '.' char.
It will really be much easier for you to figure out what you need at the cmd-line.
Set a variable with 1 sample fileName
myTestFileName=staticPart.dynamicPart.pdf
and then use echo combined with the variable modifiers to see the results.
echo ${myTestFileName##*.}
echo ${myTestFileName#*.}
echo ${myTestFileName##.*}
echo ${myTestFileName#.*}
echo ${myTestFileName%%.*}
etc.
Also notice how I combine a modified variable value with a plain string (.pdf), in unsecuredName=${file%%.*}.pdf
IHTH

Resources