LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-06-2016, 07:30 AM   #1
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Rep: Reputation: 103Reputation: 103
if [ ${filename##*.} != "gz" ]


I don't understand the meaning of the sentence written in the subject. What I don't understand exactly is the meaning of ## in this case. What does it mean?

How does it combine with a ${variable} construction?
 
Old 08-06-2016, 08:00 AM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,703

Rep: Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896Reputation: 5896
It removes the longest match from the front of the string. For example if the file name is something.tar.gz a single # would be tar.gz. And ## would be gz.

http://tldp.org/LDP/abs/html/string-manipulation.html
 
1 members found this post helpful.
Old 08-06-2016, 08:01 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,309
Blog Entries: 3

Rep: Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721Reputation: 3721
That is an example of Bash's parameter expansion. Specifically, it is substring removal.
 
1 members found this post helpful.
Old 08-06-2016, 08:24 AM   #4
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
I'm currently reading the advanced bash scripting tutorial from tldp.org, and there are a lot of examples at the beginning using notions that are explained later on. Even so, I'm still trying to understand as much as possible at this stage so as to understand it much better later on when they're actually explained

I still haven't understood it fully at the stage, but both your links are useful, so I guess I'll get it eventually.

@michaelk what do you mean by 'the front of the string'? Do you mean to say the beginning?

So let's say we have:
filename=something.tar.gz
if [ ${filename##.*} != "gz" ]

Would it be a match in this case? If so, I don't understand the .* at the end, 'cause that's where .tar.gz or .gz should be, shouldn't it? It's not that straightfoward

P.S.
I've just read this from turbocapitalist's link. Made things much more comprehensible:

Get name without extension
${FILENAME%.*}
⇒ bash_hackers.txt
Get extension
${FILENAME##*.}
⇒ bash_hackers.txt
Get directory name
${PATHNAME%/*}
⇒ /home/bash/bash_hackers.txt
Get filename
${PATHNAME##*/}
⇒ /home/bash/bash_hackers.txt

Last edited by vincix; 08-06-2016 at 08:36 AM.
 
Old 08-06-2016, 09:07 AM   #5
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
It's not a regular expression, it's a shell parameter expansion, so .* is not a pattern

.* in a parameter expansion means a dot char '.' followed by zero or more characters
 
Old 08-06-2016, 09:26 AM   #6
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
Yeah, I'm starting to get it.

One other question. Let's say I'm in /home/user. If I try:

echo ${PWD%/*}

I get:
/home

Is there a way I can get only the "home" string using substring removal without turning to another tool, such as sed, or tr or whatever?

Now I think it's a little bit of a silly question, 'cause you either start from the beginning or the end with subtring removal, so if you start from the end of the string, the first character of the string "/" is obviously going to be there

Last edited by vincix; 08-06-2016 at 09:28 AM.
 
Old 08-06-2016, 07:21 PM   #7
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
This is a bash trick
Code:
path=(${PWD//\// })
echo ${path[0]}
Basicaly it does:

Code:
# replace all slashes (/) with a space in $PWD value
${PWD//\// }

# use the string delimited with spaces as array values
# array=($string_with_spaces)
path=(${PWD//\// })

# echo first element
echo ${path[0]}
Note: this only works with directories names that contain no spaces of course
(A work around is possible with IFS setting)

Last edited by keefaz; 08-06-2016 at 07:26 PM.
 
1 members found this post helpful.
Old 08-07-2016, 08:35 PM   #8
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
PE does what is says, but you can of course take the o/p of one PE and feed it into another PE to eg remove the leading '/' ...
 
Old 08-08-2016, 03:34 AM   #9
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,794

Rep: Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201Reputation: 1201
Code:
if [ "${filename##*.}" != "gz" ]
is not 100% correct because it also (not) matches the file mame "gz".
To only (not) match a ".gz" name I suggest
Code:
if [[ $filename != *.gz ]]

Last edited by MadeInGermany; 08-08-2016 at 03:35 AM.
 
3 members found this post helpful.
Old 08-09-2016, 12:32 AM   #10
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
There's also the '=~ ' operator
http://www.tldp.org/LDP/abs/html/bas...#REGEXMATCHREF
http://www.computerworld.com/article...pressions.html
 
1 members found this post helpful.
Old 08-09-2016, 04:21 AM   #11
aragorn2101
Member
 
Registered: Dec 2012
Location: Mauritius
Distribution: Slackware
Posts: 567

Rep: Reputation: 301Reputation: 301Reputation: 301Reputation: 301
It is string manipulation in Bash. Check page 122 in the following:

http://www.tldp.org/LDP/abs/abs-guide.pdf
 
Old 08-09-2016, 12:20 PM   #12
vincix
Senior Member
 
Registered: Feb 2011
Distribution: Ubuntu, Centos
Posts: 1,240

Original Poster
Rep: Reputation: 103Reputation: 103
Quote:
Originally Posted by MadeInGermany View Post
Code:
if [ "${filename##*.}" != "gz" ]
is not 100% correct because it also (not) matches the file mame "gz".
To only (not) match a ".gz" name I suggest
Code:
if [[ $filename != *.gz ]]
I'm not sure if I follow you. So if the file is called "gz.tar", for instance, you mean to say that the condition will not verify, basically, if the file has the .gz extension? I'm not sure you're right. Can you expand on that?

Ok, now I get it. You mean to say that if there's a file called "gz" (without any extension), then it would take it (or not) to be a .gz archive, for instance, so it would be a completely correct condition. Yes, nice observation. Thank you for that

Last edited by vincix; 08-09-2016 at 12:26 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Wget "cannot write to"/ "filename too long" problem sybrenkooistra Linux - Newbie 6 09-03-2012 09:53 PM
[SOLVED] "tail -n 1 filename" error while "head -n 1 filename" is ok? type8code0 Linux - Newbie 3 03-21-2011 06:10 AM
[SOLVED] move all ".txt" files, adding parent directory to filename mostofmonty Linux - Newbie 9 09-15-2009 08:39 AM
From BASH, "Play <filename.wav" gives obsolete oss interface message ericcarlson Fedora 3 09-14-2004 06:20 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 07:21 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration