LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash: Pattern matchin - how to do matching on a variable? (https://www.linuxquestions.org/questions/programming-9/bash-pattern-matchin-how-to-do-matching-on-a-variable-774125/)

SQADude 12-07-2009 10:25 PM

Bash: Pattern matchin - how to do matching on a variable?
 
This is similar to the question asked on thread: http://www.linuxquestions.org/questi...-bash.-691571/

However, it's a bit different.

In perl, the code would be:
Code:

my $outPut = `ls -ltr foo`;
# The output of ls -ltr has 7 columns of data, with the filename
# in the last column


$outPut =~ /^*\ (\S+)$/;
my $fileName = $1;

The above code will parse the filename from the output of an ls -ltr command. How would I do that in BASH?

jhwilliams 12-07-2009 10:52 PM

awk would be well suited for this:
Code:

ls -ltr | awk '{ print $8 }'
But then what's the point of the -l flag?

Or, sometimes I do something like this with grep:

Code:

if [ `echo $foo | grep -Ec "regex"` -eq 1 ]; then
  # do stuff
else
  # do other stuff
fi


tuxdev 12-07-2009 10:54 PM

Same way described by ntubski in that thread - regex pattern matching. You can access the parenthesized matches in the BASH_REMATCH array.

bit-head 12-07-2009 10:55 PM

My point as well. You can use just:

Code:

ls -tr foo
to get the file name alone. Also you can make a single column with:

Code:

ls -1tr
(hint: that's a "one" not an "l"

ghostdog74 12-07-2009 10:57 PM

is getting file names so difficult? use shell expansion, and DON'T use ls -l + awk to get file names unless you are pretty sure files don't have spaces.
Code:

for myfile in *
do
 echo "$myfile"
done


tuxdev 12-07-2009 10:59 PM

Actually, you should *never* try to do any kind of parsing with the output of ls - http://mywiki.wooledge.org/ParsingLs

pixellany 12-07-2009 11:00 PM

8 columns--more if the file is a link

For the filename:
Code:

ls -l|sed -r 's/ +/ /g'|cut -d " " -f8
OR:
ls -l|awk '{print $8}'


jhwilliams 12-07-2009 11:06 PM

Quote:

Originally Posted by tuxdev (Post 3783516)
Actually, you should *never* try to do any kind of parsing with the output of ls - http://mywiki.wooledge.org/ParsingLs

Well, the issue of having an \n embedded in a filename is not really a legitimate concern. Anyone who were to do this would surely be fired, and their files would be renamed by their replacement. But the unix/linux timestamp portability point is probably a legitimate cause for concern.

ghostdog74 12-08-2009 12:20 AM

Quote:

Originally Posted by tuxdev (Post 3783516)
Actually, you should *never* try to do any kind of parsing with the output of ls - http://mywiki.wooledge.org/ParsingLs

not when trying to get other fields besides file names.

catkin 12-08-2009 12:41 AM

Quote:

Originally Posted by ghostdog74 (Post 3783566)
not when trying to get other fields besides file names.

Even then, for maximum robustness; knowing the (possibly pathological!) filename, the "other fields" data can be found using the stat command.

Possibly over-defensive in many real-life situations and surely slow but appealing to those of us given aversion therapy in the school of "if it can go wrong, it will go wrong".

ghostdog74 12-08-2009 01:23 AM

well, ls uses the same "stat" libraries to retrieve those information as well. Also, stat may not be in some Unix platforms, but ls is.

catkin 12-08-2009 01:36 AM

Quote:

Originally Posted by ghostdog74 (Post 3783610)
well, ls uses the same "stat" libraries to retrieve those information as well. Also, stat may not be in some Unix platforms, but ls is.

There are no right answers, only choices with various pros and cons. When deciding which choices to make, we balance the pros and cons, considering: maintainability, portability (thanks for that), skill level, robustness and time (both development and execution) ... .

The "sweet spot" will vary depending on usage -- a quick-and-dirty "one off", a cross-platform installation utility, a backup script, system-wide vs. private usage etc.

Are there many *n*x platforms that don't have stat -- apart from very cut-down versions such as BusyBox (which may have stat -- I don't know)?

SQADude 12-08-2009 06:51 PM

Quote:

Originally Posted by jhwilliams (Post 3783505)
awk would be well suited for this:
Code:

ls -ltr | awk '{ print $8 }'

(I don't know awk or sed so bear with me - I might make incorrect comments)

If use the code above, it seems to work, as long as the filename does not have spaces in the filename .

Quote:

But then what's the point of the -l flag?
Without the -l flag, only the filenames are displayed. At least with the -ltr option, I know that the filename is anything that follows the time/date of the file.

Quote:

Or, sometimes I do something like this with grep:

Code:

if [ `echo $foo | grep -Ec "regex"` -eq 1 ]; then
  # do stuff
else
  # do other stuff
fi


I need to extract the filename, not do a comparison. I can do this easily in Perl. Not so easy in Bash.

jhwilliams 12-08-2009 07:09 PM

Quote:

Originally Posted by SQADude (Post 3784721)
Without the -l flag, only the filenames are displayed. At least with the -ltr option, I know that the filename is anything that follows the time/date of the file.

This doesn't make sense to me at all.

Quote:

I need to extract the filename, not do a comparison. I can do this easily in Perl. Not so easy in Bash.
It isn't a comparison really -- that's a control structure you can use to perform various actions if a file name matches a regular expression. Anyway, use grep.

chrism01 12-08-2009 07:19 PM

SQADude is saying that

ls -l

always produces one 'record' per file per line of output, and anything(!) after the date/timestamp in each rec is the filename, with or without spaces in it.


All times are GMT -5. The time now is 03:12 PM.