"Command not found" piping a variable to cut when output stored in a variable [duplicate] - linux

This question already has answers here:
How to pass the value of a variable to the standard input of a command?
(9 answers)
Closed 5 years ago.
In a bash script I am using a variable to hold a path like this:
MY_DIR=/just/a/string/to/my/path
And I want to remove the last two parts of it so it looks like this:
/just/a/string
I am using 'cut' to do it, like this:
echo $MY_DIR | cut -d'/' -f-4
The output is what I expect. Fine.
But I want to store in an other variable, like this:
MY_DIR2=$($MY_DIR | cut -d'/' -f-4)
When I execute the script I get the error:
... /just/a/string/to/my/path: No such file or directory
Why is the direct output with echo working, but storing the output in a variable is not?

You need to pass an input string to the shell command using a pipeline in which case cut or any standard shell commands, reads from stdin and acts on it. Some of the ways you can do this are use a pipe-line
dir2=$(echo "$MY_DIR" | cut -d'/' -f-4)
(or) use a here-string which is a shell built-in instead of launching a external shell process
dir2=$(cut -d'/' -f-4 <<< "$MY_DIR")

Use the grave accent(`) to emulate a command, and use echo too.
MY_DIR2=`echo $MY_DIR | cut -d'/' -f-4`

Related

Piping into a part of bash command stored in variable [duplicate]

This question already has answers here:
Conditional step in a pipeline
(2 answers)
Can I make a shell function in as a pipeline conditionally "disappear", without using cat?
(1 answer)
Closed 4 months ago.
EMPTY_VAR=''
MMDDYYYY='6.18.1997'
PIPE_VAR=' | xargs echo "1+" | bc'
echo "$MMDDYYYY" | cut -d "." -f 2${EMPTY_VAR}
>> 18
Command above would give me correct output, which is 18, but if I try to use PIPE_VAR instead it would give me bunch of errors:
echo "$MMDDYYYY" | cut -d "." -f 2${PIPE_VAR}
cut: '|': No such file or directory
cut: xargs: No such file or directory
cut: echo: No such file or directory
cut: '"1+"': No such file or directory
cut: '|': No such file or directory
cut: bc: No such file or directory
OR:
echo "$MMDDYYYY" | cut -d "." -f 2"$PIPE_VAR"
cut: invalid field value ‘| xargs echo "1+" | bc’
Try 'cut --help' for more information.
What I'm really trying to find out is that even possible to combine commands like this?
You can't put control operators like | in a variable, at least not without resorting to something like eval. Syntax parsing comes before parameter expansion when evaluating the command line, so Bash is only ever going to see that | as a literal character and not pipeline syntax. See BashParsing for more details.
Conditionally adding a pipeline is hard to do well, but having a part of the pipeline conditionally execute one command or another is more straightforward. It might look something like this:
#!/bin/bash
MMDDYYYY='6.18.1997'
echo "$MMDDYYYY" | cut -d "." -f 2 |
if some_conditional_command ; then
xargs echo "1+" | bc
else
cat
fi
It looks like you're trying to calculate the next day. That's hard to do with plain arithmetic, particularly with month/year ends.
Let date do the work. This is GNU date. It can't parse 6.18.1997 but it can parse 6/18/1997
for MMDDYYYY in '2.28.1996' '2.28.1997'; do
date_with_slashes=${MMDDYYYY//./\/}
next_day=$(date -d "$date_with_slashes + 1 day" '+%-m.%-d.%Y')
echo "$next_day"
done
2.29.1996
3.1.1997

Bash how to loop through the output of a command and assign that output to variable [duplicate]

This question already has answers here:
Looping through the content of a file in Bash
(16 answers)
Closed 11 months ago.
I have a for loop in my bash script.
for dir in $directories
do
dockerfile=$(find ./repo/$dir -name "Dockerfile");
docker build -f $dockerfile . -t $dir:version;
new_image=$(echo "$dir:version" | cut -d '/' -f2);
done
How can I pass $new_image output to another variable?
If I do something like this
new_image=$(echo "$image:version" | cut -d '/' -f2 >> list_images.txt)
I get the list of docker images in my .txt file but is there a way to pass the output to a variable? And update that variable value on each iteration?
The expected output after one iteration is something like
testing1:version
So when the for loop stops executing I get something like this in my .txt file.
testing1:version
kubernetes:version
node:version
And this is what I need, I can't figure out a better way to do this.
Using an answer, because the comments make it unreadable.
Do I understand correctly that you want:
for dir in $directories
do
dockerfile=$(find ./repo/$dir -name "Dockerfile");
docker build -f $dockerfile . -t $dir:version;
echo "$dir:version" | cut -d '/' -f2
done > list_images.txt
or do you actually have a need for the variable(s) further-on in your script?
And
new_image=$(echo "$dir:version")
trimmed=${new_image#*/}
will do your cut in bash, but that's just for bonuspoints :-)

How to store part of the file name into a variable using shell script? [duplicate]

This question already has answers here:
How do I set a variable to the output of a command in Bash?
(15 answers)
How do I remove the file suffix and path portion from a path string in Bash?
(15 answers)
Closed 1 year ago.
I have a file 20210823_Club_Member_Name_by_ID.txt. I want to get only the first element of the file name which is 20210823 and store it into a variable using shell script.
Currently, my code can print out the first element in the terminal but I also want to store it into a variable for further usage.
file='20210823_Club_Member_Name_by_ID.txt'
echo "$file" | awk -F'[_.]' '{print $1}'
// I try to store it like below, but it does not work
fileDate= echo "$file" | awk -F'[_.]' '{print $1}'
echo $fileDate
As Jetchisel commented, you can use shell parameter expansion to safely extract the value. The %% operator removes as much of the matching text as possible, starting from the end of the string; if we use _* then this will essentially remove everything after and including the first underscore.
file='20210823_Club_Member_Name_by_ID.txt'
fileDate="${file%%_*}"
The fileDate variable will now contain 20210823.

Bash loop with grep containing variable [duplicate]

This question already has an answer here:
Tilde not expanded when quoting on the right hand side of a Bash variable assignment [duplicate]
(1 answer)
Closed 1 year ago.
I have a function which should loop through every customer in an array and execute a grep to that directory.
test(){
set -x;
export customers=( customer1 customer2 customer3 );
export repo_path="~/repodir";
export output_path='/tmp';
for i in "${customers[#]}"
do
echo "${repo_path}/PEC/repo-${i}/build.yml"
grep 'link: ' $repo_path/PEC/repo-$i/build.yml | cut -d '/' -f 2 | sed 's/.git//g'
done | sort -u > ${output_path}/repos.txt
echo "${output_path}/repos.txt";
}
For some reason I get the following error message:
grep: ~/repodir/PEC/customer1/build.yml: No such file or directory
But when I check that exact same path I can see and read the file...
The first echo command also doesn't seem to be executing.
When I replace grep 'link: ' $repo_path/PEC/repo-$i/build.yml with grep 'link: ' ~/repodir/PEC/repo-$i/build.yml it does work.
I have tried various ways to define the variable like ${repo_path}, adding different types of quotes, ... So I basically don't know what I can do to make it work anymore.
$HOME is an environment variable, that is set to contain the home folder of the current user. The terminal session should have access to this environment variable at all times, unless this has been removed.
~ is a shell expansion symbol, one of the symbols that is processed before the actual command is performed. ~ alone expands to the value of $HOME.
Your code,
export repo_path="~/repodir";
the ~ is in a string and may not be processed, if you want to use a ~ try escaping the character. For readability using the $HOME variable would be simpler.

Read first characters of a variable in bash script? [duplicate]

This question already has answers here:
In Bash, how can I check if a string begins with some value?
(13 answers)
Closed 6 years ago.
I have a file where i get some informations through a bash script to put data in a DB table and i'd like to know how to read the first characters of a variable because if it starts with "CE-" that line's data will go into a table if not they must be inserted in an other one, how can i do this?
Like this-
var=CE-xxxxx
echo "$var"
output- CE-xxxxx
var2=$(echo "$var" | cut -c 1-3)
echo "$var2"
output- CE-
Then you can check if $var2 matches your criteria and use it further.
You can use cut to get the bytes that you need:
V="CE-IMPORTANT"
I=$(echo $V | cut -b 4-)
If you want to use the - as separator:
I=$(echo $V | cut -d '-' -f 2)
In both cases you get "IMPORTANT" in I var

Resources