LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 11-12-2020, 01:14 PM   #1
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Question Simple bash string manipulation - well it should be


I have a file name, abcdefgh.mp4 and I want to just get the last four characters of the name "efgh" (okay - I know files in linux don't have extensions like in Windoze it's alll just part of the name)


I can do it with an intermediate variable, but I want one neat bit of bash:
Code:
$ echo $ff  ${ff%.*} 
5f391985dc5a423cb7d31.mp4 5f391985dc5a423cb7d31
So far so good and I could do this:
Code:
$ X=${ff%.*} 
$ echo ${X: -4}
7d31
Or this, but it presumes the filenames are always the same length:
Code:
~$ ff=5f391985dc5a423cb7d31.mp4
~$ echo ${ff:17:4}
7d31
But I would like a one liner please

Last edited by GPGAgent; 11-12-2020 at 01:21 PM.
 
Old 11-12-2020, 01:27 PM   #2
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
Accounting for the extension in this case, you could use the string length - the extension length (4 including the .).
Code:
ff='5f391985dc5a423cb7d31.mp4'
echo "${ff:$((${#ff} - 8)):4}"
 
1 members found this post helpful.
Old 11-12-2020, 01:36 PM   #3
computersavvy
Senior Member
 
Registered: Aug 2016
Posts: 3,342

Rep: Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484
Code:
 X=`basename -s .mp4 12345dr61.mp4`; echo ${X: -4}
would give you exactly what you asked for in one line.
 
Old 11-12-2020, 02:35 PM   #4
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by computersavvy View Post
Code:
 X=`basename -s .mp4 12345dr61.mp4`; echo ${X: -4}
would give you exactly what you asked for in one line.
Cheers, I should have been more explicit, I meant one command with no intermediate variable
 
Old 11-12-2020, 02:37 PM   #5
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by individual View Post
Accounting for the extension in this case, you could use the string length - the extension length (4 including the .).
Code:
ff='5f391985dc5a423cb7d31.mp4'
echo "${ff:$((${#ff} - 8)):4}"
Neat, I'll use it thanks
 
Old 11-12-2020, 07:54 PM   #6
computersavvy
Senior Member
 
Registered: Aug 2016
Posts: 3,342

Rep: Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484
Quote:
Originally Posted by GPGAgent View Post
Cheers, I should have been more explicit, I meant one command with no intermediate variable
If you are looking at passing the filename to your command instead of hard coding it (as in a script) then you will need to use the default bash command line internal variables $0, $1, etc. anyway. One of the major strengths of bash is that it allows the use of variables either on the command line or in scripts.

With that said,
Code:
 ls *.mp4 | sed -n s/.mp4$//p | grep -o ....$
will give you the last 4 characters of every filename ending with .mp4 after stripping the "extension" off it. Without using a variable as asked.

Last edited by computersavvy; 11-12-2020 at 07:55 PM.
 
1 members found this post helpful.
Old 11-13-2020, 07:58 AM   #7
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Thumbs up

Quote:
Originally Posted by computersavvy View Post
If you are looking at passing the filename to your command instead of hard coding it (as in a script) then you will need to use the default bash command line internal variables $0, $1, etc. anyway. One of the major strengths of bash is that it allows the use of variables either on the command line or in scripts.

With that said,
Code:
 ls *.mp4 | sed -n s/.mp4$//p | grep -o ....$
will give you the last 4 characters of every filename ending with .mp4 after stripping the "extension" off it. Without using a variable as asked.
Another fine solution, cheers


I like examples because I go over them to see how they work and this helps me write and configure my own versions to suit.
 
Old 11-13-2020, 08:17 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,792

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
backtick, basename, sed, grep are all new processes, they cost much more (in resources, like time, cpu, ram) than the built-in bash alternatives.
So why do you want a oneliner?
Code:
echo ${ff: -8: -4}
 
Old 11-13-2020, 10:02 AM   #9
computersavvy
Senior Member
 
Registered: Aug 2016
Posts: 3,342

Rep: Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484Reputation: 1484
Quote:
Originally Posted by pan64 View Post
backtick, basename, sed, grep are all new processes, they cost much more (in resources, like time, cpu, ram) than the built-in bash alternatives.
So why do you want a oneliner?
Code:
echo ${ff: -8: -4}
I don't know why, but GPGAgent specifically asked for no variable in the one-liner. The only way I know to do that requires chaining processes together instead of using the built-in variable tools of bash. Yours works cleanly and efficiently but does require a variable be used.
 
1 members found this post helpful.
Old 11-14-2020, 08:15 AM   #10
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Talking

Quote:
Originally Posted by computersavvy View Post
I don't know why, but GPGAgent specifically asked for no variable in the one-liner. The only way I know to do that requires chaining processes together instead of using the built-in variable tools of bash. Yours works cleanly and efficiently but does require a variable be used.
When I said a one liner, I really meant no intermediate variables or even piping temp results to another process, and this solution is what i was looking for but couldn't get my head around the double negative as it were:
Code:
$ ff=12345678.mp3
jonke@charlie:~$ echo ${ff: -8: -4}
5678
jonke@charlie:~$
This perfect and yes I did know that the syntax for strings is
Code:
${ff:start:length}
so using a negative start point and a negative length is obviously going to work, I just wasn't thinking in a negative way!!!


So -8 means start 8ch in from the end so
Code:
jonke@charlie:~$ echo ${ff: -8:}

jonke@charlie:~$
aha, returns nothing because you're not specifying a length,so lets go for 8ch length
Code:
jonke@charlie:~$ echo $ff   ${ff: -8:8}
1234567890987654321abcd.mp3 abcd.mp3
jonke@charlie:~$
but I only want 4ch
Code:
jonke@charlie:~$ echo $ff   ${ff: -8:4}
1234567890987654321abcd.mp3 abcd
jonke@charlie:~$
so there we have it
Code:
echo $ff   ${ff: -8:4}

You don't need the length to be negative - obvious when you break it down, cheers to everyone who replied.
 
Old 11-14-2020, 09:52 AM   #11
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,792

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
Quote:
Originally Posted by GPGAgent View Post

So -8 means start 8ch in from the end so
Code:
jonke@charlie:~$ echo ${ff: -8:}

jonke@charlie:~$
aha, returns nothing because you're not specifying a length,so lets go for 8ch length
Code:
jonke@charlie:~$ echo $ff   ${ff: -8:8}
1234567890987654321abcd.mp3 abcd.mp3
jonke@charlie:~$
you do not need the : at the end:
Code:
echo ${ff: -8}
 
Old 11-14-2020, 09:57 AM   #12
GPGAgent
Senior Member
 
Registered: Oct 2018
Location: Surrey UK
Distribution: Mint 20 xfce 64bit
Posts: 1,026

Original Poster
Blog Entries: 3

Rep: Reputation: 133Reputation: 133
Quote:
Originally Posted by pan64 View Post
you do not need the : at the end:
Code:
echo ${ff: -8}
That's correct, left it in by mistake - cut 'n paste and didn't check it, btw I should mention the space is important and this is the alternate a\nd perhaps more accurate syntax
Code:
jonke@charlie:~$ echo ${ff:(-8)}  # alternate syntax
5678.mp3
jonke@charlie:~$ echo ${ff: -8}   # space before -8 is important
5678.mp3
jonke@charlie:~$ echo ${ff:-8}    # no, incorrect
12345678.mp3
jonke@charlie:~$
cheers
 
1 members found this post helpful.
Old 11-14-2020, 10:08 AM   #13
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,792

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
echo ${ff:-8} is correct, just it has a different meaning, see: ${parameter:-word}
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
bash string manipulation kpachopoulos Programming 3 06-17-2007 06:45 PM
string manipulation in BASH ovince Programming 4 04-16-2007 07:15 PM
String manipulation with BASH script King V Programming 9 04-21-2006 03:15 PM
Well well well..what do we have here? DaBlade Linux - News 4 10-03-2005 10:07 AM
bash + string manipulation dave bean Programming 7 02-16-2005 11:16 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 07:26 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