bash reading string with spaces as parameter - string

I found on a forum how to solve when a function is called with more parameters and each as string with spaces, but how to read string with spaces from input, I mean when somebody calls my script.
In this case, user should send two txt files addresses. So, I know the suffix, but he could also send files that haven't got that suffix. So, is there any way how to read the two file addresses?

The script arguments are kept in so called "positional parameters". For example, if the script is called as
script.sh /path/to/1.txt 2.csv
$1 will contain the first file path and $2 the second one.

Related

removing the trailing extension from a string in Python3

I have the python script below to iterate over all files ending with 'mkv', and print the same string without the 'mkv' at the end.
But, instead it prints the original filename including the 'mkv', why??
files=os.system('find /media/radamand/230_GB -name *mkv')
for file in str(files):
converted_filename=file[0:-3]
print(converted_filename)
Your os.system call executes your find command, sends its output to your interpreter standard output stream (which is why you're seeing your matching files including the "mkv" at the end, as this output is not the result of your print function in your later code), and then simply returns the exit code.
So your files variable actually gets an assignment of the integer 0.
Your for loop then casts files from an int into a string ('0') and thus your for loop now actually means: "loop through each character of the string files" (there is only one however), which, in this case, due to your slicing of [:-3] on a string of only one character, evaluates as an empty string which gets passed to your print function.
So, os.system isn't designed for what you are trying to achieve.
If you potentially have other folders in the parent folder you are searching, that may also have the filenames you are looking for, then I would recommend using the glob module.
import glob
files = glob.glob("/media/radamand/230_GB/*mkv") # Returns a list of strings for matched files
for file in files:
print(file[:-3])
You can add and set the keyword arguments recursive and/or include_hidden to True if required.
If, however, you are only looking for the files in the current folder, you can use fnmatch:
import fnmatch
import os
for file in os.listdir("/media/radamand/230_GB"):
if fnmatch.fnmatch(file, "*mkv"):
print(file[:-3])

Operating on a file with overly long name

When I set up the ProtonMail Bridge CLI, it generated a hierarchy in my .password-store where the top level is called protonmail-credentials. This contains a subfolder where the name is a gibberish string enclosed in single quotes with--according to wc -c--153 characters. The name of the item under this is itself a 93-character string.
I would like to be able to operate on this item with pass, but wildcards apparently don't work for paths in pass, and dealing with such absurdly long strings which differ from setup to setup by typing everything out is not at all viable.
I am able to isolate the subfolder name with ls -1 .password-store/protonmail-credentials, which gives me the string beginning 'cHJv and continuing onward. I thought I could assign this to an environment variable with export $LONGDIRNAME=$(ls -1 .password-store/protonmail-credentials), but bash throws a 'not a valid identifier' error and thinks I'm trying to set the variable to a string beginning `=cHJv. I do not know why it is adding a backtick and equals sign to the string before attempting to set the variable.
Renaming either of these breaks ProtonMail Bridge's functionality, so mv is not an option either. What should I do with these strings to make the usable in pass?

Adding multiple user inputs into one variable in Bash

I am fairly new to unix bash scripting and need to know if this is possible. I want to ask user for their input multiple times and then store that input in to one variable.
userinputs= #nothing at the start
read string
<code to add $string to $userinputs>
read string
<code to add $string to $userinputs> #this should add this input along with the other input
so if the user enters "abc" when asked first time, it add's "abc" in $userinputs
then when asked again for the input and the user enters "123" the script should store it in the same $userinputs
this would make the $userinput=abc123
The usual way to concat two strings in Bash is:
new_string="$string1$string2"
{} are needed around the variable name only if we have a literal string that can obstruct the variable expansion:
new_string="${string1}literal$string2"
rather than
new_string="$string1literal$string2"
You can also use the += operator:
userinputs=
read string
userinputs+="$string"
read string
userinputs+="$string"
Double quoting $string is optional in this case.
See also:
How to concatenate string variables in Bash?
You can concatentate variables and store multiple strings in the same one like so:
foo=abc
echo $foo # prints 'abc'
bar=123
foo="${foo}${bar}"
echo $foo # prints 'abc123'
You can use the other variables, or the same variable, when assigning to a variable, e.g. a="${a}123${b}". See this question for more info.
You don't have to quote the strings you're assigning to, or do the ${var} syntax, but learning when to quote and not to quote is a surprisingly nuanced art, so it's often better to be safe than sorry, and the "${var}" syntax in double quotes is usually the safest approach (see any of these links for more than you ever wanted to know: 1 2 3).
Anyway, you should read into a temporary variable (read, by default, reads into $REPLY) and concatentate that onto your main variable, like so:
allinput=
read # captures user input into $REPLY
allinput="${REPLY}"
read
allinput="${allinput}${REPLY}"
Beware that the read command behaves very differently depending on supplied switches and the value of the IFS global variable, especially in the face of unusual input with special characters. A common "just do what I mean" choice is to empty out IFS via IFS= and use read -r to capture input. See the read builtin documentation for more info.

In BASH, can we assign and display the value in the variable _ (underscore)?

Answering to the following question:
Allowed characters in linux environment variable names #aiden-bell writes that the following patterns gives all allowed shell variable names in BASH : [a-zA-Z_]+[a-zA-Z0-9_]*
I found this to be true. In fact I can export value _="Just for fun". Unfortunately though, whenever I print it I get __bp_preexec_invoke_exec
I went through this thread and while it is instructive it doesn't actually answer my question. Irrespective of whatever the shell might do with the variable $_, can I use it for my own means? Also, whatever exactly is __bp_preexec_invoke_exec? Thanks and regards.
You can assign to the special parameter _, but the shell will also update its value after each command. Typically, you only use it as a dummy variable where you don't care about the result, such as in something like
while read _ second _ ; do ...; done < input.txt
where you only care about the second column of each input line.
From the man page:
_ At shell startup, set to the absolute pathname used to invoke
the shell or shell script being executed as passed in the envi-
ronment or argument list. Subsequently, expands to the last
argument to the previous command, after expansion. Also set to
the full pathname used to invoke each command executed and
placed in the environment exported to that command. When check-
ing mail, this parameter holds the name of the mail file cur-
rently being checked.

Returning Filename with wildcards in VFP 9

I am trying to locate the full name of a file using a wildcard. The code I have is:
MLCNo=crjbis.ffromlot
subfolder=LEFT(mlcno,3)
filename=SYS(2000,'S:\MLC\MLC#\'+subfolder+'xx\'+mlcno+'21391*.pdf')
pathname="S:\MLC\MLC#\"+subfolder+"xx\"+filename
Pathname is passed to a print function to print the file. All of this works great if I don't use a variable in the SYS function (even with a wildcard). I should add that there will only ever be one file returned by the wildcard. Is there another way to do this?
Thanks!!!
Tammy

Resources