LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Bracket wildcard usage command line (https://www.linuxquestions.org/questions/linux-general-1/bracket-wildcard-usage-command-line-4175648301/)

oliveoyl 02-14-2019 09:48 AM

Bracket wildcard usage command line
 
Hi,

I'm trying to use bracket wildcard on the command line like this:

grep SOMETHING /var/log/node/2019/02/[01-07]/messages


Here is the layout to give you an idea:

## pwd
/var/log/node/2019/01

## ls
01 03 05 07 09 11 13 15 17 19 21 23 25 27 29 31
02 04 06 08 10 12 14 16 18 20 22 24 26 28 30

What is the correct syntax to use bracket wildcard like I want to above?

Thank you.

l0f4r0 02-14-2019 09:53 AM

Code:

grep "SOMETHING" /var/log/node/2019/02/{01..07}/messages

oliveoyl 02-14-2019 01:15 PM

That worked great from the command line!

Now I tried to put it in a script with 01 and 07 as variables but it won't read it:



## DAY1=01; DAY7=07
## echo $DAY1
01
## echo $DAY7
07
## grep "SOMETHING" /var/log/node/2019/02/{$DAY1..$DAY7}/messages
grep: /var/log/node/2019/02/{01..07}/messages: No such file or directory

teckk 02-14-2019 01:50 PM

Code:

echo {01..07}
01 02 03 04 05 06 07

Code:

a=01
b=07
echo {"$a".."$b"}
{01..07}

Code:

c=({01..07})
for i in "${c[@]}"; do echo "$i"; done
01
02
03
04
05
06
07

Code:

c=({01..07})
for i in "${c[@]}"; do
    echo "grep "SOMETHING" /var/log/node/2019/02/"$i"/messages"
done
grep SOMETHING /var/log/node/2019/02/01/messages
grep SOMETHING /var/log/node/2019/02/02/messages
grep SOMETHING /var/log/node/2019/02/03/messages
grep SOMETHING /var/log/node/2019/02/04/messages
grep SOMETHING /var/log/node/2019/02/05/messages
grep SOMETHING /var/log/node/2019/02/06/messages
grep SOMETHING /var/log/node/2019/02/07/messages

Code:

for i in /var/log/node/2019/01/{01..30}/messages; do
    echo "grep 'SOMETHING' "$i""
done


rknichols 02-14-2019 02:05 PM

Quote:

Originally Posted by oliveoyl (Post 5962070)
## DAY1=01; DAY7=07
## echo $DAY1
01
## echo $DAY7
07
## grep "SOMETHING" /var/log/node/2019/02/{$DAY1..$DAY7}/messages
grep: /var/log/node/2019/02/{01..07}/messages: No such file or directory

The problem is with the order in which bash does expansions. Brace expansion is performed before parameter expansion, and those literal characters "$DAY1..$DAY7" are not a legitimate brace expression. There is no simple way to do what you want in bash. You need to do one of:
  1. write a loop to generate the set of strings,
  2. use an external command like seq with its --format option, or
  3. perhaps use zsh, where "{$Var1..$Var2}" does what you want here.

MadeInGermany 02-14-2019 03:47 PM

Better check for existence in the loop and skip non-existent files
Code:

for f in /var/log/node/2019/01/{01..30}/messages; do
    [ -f "$f" ] || continue
    echo grep 'SOMETHING' "$f"
done


l0f4r0 02-15-2019 06:50 AM

Since OP has requested a solution with variables, I suggest the following:
Code:

#!/bin/bash
startVar=01
endVar=07
for ((i=startVar;i<=endVar;i++))
do
        if ((i<10))
        then
                [[ -f /var/log/node/2019/02/0$i/messages ]] && grep "SOMETHING" "/var/log/node/2019/02/0$i/messages"
        else
                [[ -f /var/log/node/2019/02/$i/messages ]] && grep "SOMETHING" "/var/log/node/2019/02/$i/messages"
        fi
done


MadeInGermany 02-15-2019 01:00 PM

But that looks a bit, well, sub-optimal, doesn't it?

Regarding post#1
The "bracket wildcard" is a "character set". Represents one character. So 0[0-7] or 1[0-7] works. But if the range spans over a decade then this method fails.

BTW the character set is really a "wildcard" like * because it is matched against files, and generates what it finds.
In contrast, { } generates a range unconditionally, without matching files.

l0f4r0 02-16-2019 04:30 AM

^ I agree with everything you said.
Actually, I suggested #7 because that's the only solution that came to my mind to satisfy the initial OP's request, namely to define range with variables inside a script...


All times are GMT -5. The time now is 07:41 AM.