Creating variable in loop linux - permission denied [duplicate] - linux

This question already has answers here:
Bash - Initialize variable to output of command "permission denied"
(2 answers)
Closed 3 years ago.
I am trying to run this simple script in which I loop through a series of files in a directory and want to create a variable with 'cut', to extract part of the name of the files.
I get a permission denied error and cannot figure out why.
Below is my script.
FILES=./data/*
for f in $FILES
do
NEWNAME=$($f|cut -c3-12)
echo $NEWNAME
done
The ultimate goal is to create one directory per file for downstream processing, with mkdir /path/to/new/directory/$NEWNAME.

$(stuff) executes stuff as a command and substitutes its output back into the command line. So when you do:
$($f|cut -c3-12)
it tries to execute $f as a command, and pipes its output to cut. You get an error because the file in $f doesn't have execute permission.
If you're trying to cut the contents of the variable $f, you need to echo it:
NEWNAME=$(echo "$f" | cut -c3-12)
But there's no need to use cut for this, bash has a built-in parameter expansion operator to select a substring:
NEWNAME=${f:2:10}

Related

Creating bash variables from a files in a folder [duplicate]

This question already has answers here:
Dynamic variable names in Bash
(19 answers)
Closed 7 months ago.
I have a bash script (list.sh) that lists files in a folder and assigns each filename to a bash variable:
#/bin/bash
c=0
for file in *; do
varr$c="$file";
c=$((c+1));
done
When I call this from a bash terminal with:
source list.sh
I get:
bash: varr0=07 Get the Balance Right!.mp3: command not found...
bash: varr1=190731_10150450783260347_1948451_n.jpg: command not found...
bash: varr2=199828_10150450907505347_7125763_n.jpg: command not found...
bash: varr3=2022-07-31_19-30.png: command not found...
bash: varr4=2022-08-02_12-06.png: command not found...
bash: varr5=246915_10152020928305567_1284271814_n.jpg: command not found...
I don't know how to put quotes around the file text itself, so that each varr(x) creates itself as a variable in the parent bash script, ie:
varr0="07 Get the Balance Right!.mp3"
It's not a "quote around the text" issue, it's the variable declaration varr$c that's not working. You should be using declare instead.
This script solves your problem :
#/bin/bash
c=0
for file in *; do
declare varr$c=$file;
c=$((c+1));
done
You can use the keyword declare as in
$ n=1
$ declare var_$n=20
$ echo $var_1
20
https://www.linuxshelltips.com/declare-command-in-linux/
Try this script:
c=0
for file in *; do
printf -v var$((c++)) '%s' "$file"
done
# list variables starting with var and their values
for v in ${!var*}; do
printf '%s=%s\n' "$v" "${!v}"
done
Though using an array must have been preferred over this method.

How do I pass quoted shell variables as arguments correctly? [duplicate]

This question already has answers here:
Why does shell ignore quoting characters in arguments passed to it through variables? [duplicate]
(3 answers)
Variable containing multiple args with quotes in Bash
(4 answers)
Closed 10 months ago.
As part of a build pipeline I have a shell script that zips up a directory. I want to use a variable to define which patterns should be ignored.
I'm doing something like this:
IGNORE='"*.md" "some-folder/*"'
zip -x $IGNORE -r my-zip.zip ./*
Which doesn't appear to work, the ignored files and folders are still included in the zip archive.
This does work if I create the command and then pipe it through to sh though, so I'm confident that the variable contains the correct values:
echo "zip -x $IGNORE -r my-zip.zip ./*" | sh
I think it might be something to do with the quotes, since this works as expected without them. However this fails as soon as I attempt to add more than 1 pattern to IGNORE.
IGNORE=*.md
zip -x $IGNORE -r my-zip.zip ./*
What am I missing in order to be able to pass these patterns correctly quoted?
Edit: this does also not appear to work as an array, as suggested by this question.
IGNORE='"*.md" "some-folder/*"'
EXCLUDE=($IGNORE)
zip -x ${EXCLUDE[#]} -r my-zip.zip ./*

how to copy the bash file itself to the output dir [duplicate]

This question already has answers here:
How do I know the script file name in a Bash script?
(25 answers)
Closed 2 years ago.
I want to save a copy of the bash file each time I run it. It should be saved to the output dictionary.
I am doing it like this in the mytrainrtest.sh file:
mkdir -p "${EXP_DIR}/train"
cp "${WORK_DIR}"/mytrainrtest.sh "${EXP_DIR}"/.
Now I have much more bash files with name my****** as copies of the upper one, each with different names.
How can I write the line, so the bash file will recognize its name to copy itself?
Use the $0 special variable which contains the name of the currently executing script.
cp "$0" "$exp_dir"/
Script name(path) stored in a special var $0
#!/bin/bash
echo $0
$ ./test
./test

How to echo this entire code to .bashrc without leaving out characters/strings? [duplicate]

This question already has answers here:
How do I properly quote this bash pipeline for watch?
(2 answers)
Closed 3 years ago.
How can I echo this entire piece of code to .bashrc without leaving out a single character?
# automatic logging of terminal input/output
test "$(ps -ocommand= -p $PPID | awk '{print $1}')" == 'script' || (script -f -q /home/user/.logs/terminal/manjaro/$(date +"%Y-%m- %d_%H:%M:%S")_terminal.log)
When I attempt to enter the following into terminal:
echo "the above code" >> ~/.bashrc
I get the following appended to .bashrc which is nothing like "the above code", its short about 45 or so characters.
# automatic logging of terminal input/output
test script == 'script' || (script -f -q /home/user/.logs/terminal/manjaro/2019-05- 08_09:09:19_terminal.log)
As you can see, it's leaving out A LOT of the original code. I understand this has a lot to do with the number of different quotations and placement, but without altering my code much, or at least to the point where it can still function as its intended, how can I go about getting this to echo to the file properly?
Thank you for every nanosecond of your time.
Wrap your echo'd string with single quotes ' instead of double "

Writing a bash script to find all files in a directory that start with a, and do nothing if one exist [duplicate]

This question already has answers here:
Do not show results if directory is empty using Bash
(3 answers)
Closed 4 years ago.
So I have to find all the files in the directory that start with the letter a, and list them out. This is pretty easy by doing
cd some_directory
for file in a*; do
echo "$file"
done
However I want that if there are no files present that match a*, then the for loop will not run at all. Currently, if this is the case then the shell will echo
a*
Is there a way to do this? Thank you
Your text is opposite of your title, in my answer below I've assumed the text is your intention and your title is incorrect:
globs can be made to act like this with the bash shell option "nullglob":
shopt -s nullglob
An alternative is to use find and ignore errors by piping stderr to /dev/null
for file in $(find a* 2>/dev/null); do
echo "$file"
done

Resources