3

Inside a bash script, I have an if-statement. That statement evaluates if a specific part of a string (contained in a variable) is equal to another string. I use a cut command to isolate the string part that I want to compare. I have tried few different options but this is the one I feel ought to work. but it doesn't:

Lets say that $VAR1 = "ABCDEFGHIJKLMN.csv"

if [ "$VAR1"| cut -c 7-18 = "GHIJKLMN.csv" ]; then
..do stuff..

Just to be sure I have tested the output of "$VAR1"| cut -c 7-18 and it results in the exact same string I am comparing it to.

Has anyone got an idea why this won't work?

2
  • 5
    I'm skeptical that "$VAR1"| cut -c 7-18 works as you describe - did you mean echo "$VAR1"| cut -c 7-18 perhaps? Mar 6, 2018 at 0:24
  • Wow all you guys are amazing. And all 3 solution look to be correct. I can only choose one as the accepted answer. I have to go with the answer from @JoL because he explained best what my syntax error actualy was, as well as offer a solution using cut and using the alternative substring which I didnt even know about. I will be upvoting all 3 answers. Thanks again
    – matv1
    Mar 6, 2018 at 11:37

2 Answers 2

6
if [ "$VAR1"| cut -c 7-18 = "GHIJKLMN.csv" ]; then

What this does is execute [ "$VAR1" and pipe the output to cut -c 7-18 = "GHIJKLMN.csv" ]. [ will fail because it requires its last argument to be ], and cut will fail because probably neither = nor ] are files.

I'm going to guess what you wanted was:

if [ "$(echo "$VAR1" | cut -c 7-18)" = "GHIJKLMN.csv" ]; then

Notice how I wrap the command in "$()". That causes it to execute and substitute its place with the output. Quotes are important, so the output is not split into multiple arguments for [.

Following what I believe to be best practices for bash, I would recommend doing this, instead:

if [[ "$(cut -c 7-18 <<< "$VAR1")" = "GHIJKLMN.csv" ]]; then

This avoids special interpretation of $VAR1 by echo (depending on content, it might mistake it for options), and calling 2 needless executables, [ and echo. Something special to note here is that you don't really need any of the quotes I used. [[ is a special syntax of bash, and even if the substitution had spaces, bash would not word-split it. It would also not split what was given to <<<. GHIJKLMN.csv does not have any whitespace or special characters, so it would also be fine. When in doubt though, it's a good habit to quote everything.

You could've also skipped the call to cut by doing this:

if [[ "${VAR1:6:12}" = "GHIJKLMN.csv" ]]; then

Now, everything is done in bash without executing any other program. In this syntax, instead of giving the range of characters you want like you did to cut, you provide the 0-based offset to the first character and the number of characters you want. That's 7 - 1 because cut's indices start with 1, and 12 because the range 7-18 is inclusive, so 18 - 7 + 1.

I just saw, your $VAR1 is "ABCDEFGHIJKLMN.csv". Since you cut to the end, you don't really need to specify the count:

if [[ "${VAR1:6}" = "GHIJKLMN.csv" ]]; then
2

This works:

#!/bin/bash

echo 'Beginning of script'
VAR1='ABCDEFGHIJKLMN.csv'
if [ $(echo "$VAR1" | cut -c 7-18) == "GHIJKLMN.csv" ]; then
    echo 'If condition triggered.'
fi
echo 'End of script'

This also works:

#!/bin/bash

echo 'Beginning of script'
VAR1='ABCDEFGHIJKLMN.csv'
VAR2=$(echo "$VAR1" | cut -c 7-18)
if [ "$VAR2" == "GHIJKLMN.csv" ]; then
    echo 'If condition triggered.'
fi
echo 'End of script'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.