3

I have a variable myVar in bash containing a long string that looks like this:

-rw-rw-rw- root/root 16 2018-02-12 10:03 foo_tar/baz1234_

I want to delete everything in myVar before the last slash (including the last slash), so that myVar ends up storing only baz1234_. How can I remove everything and store the result in a variable?

I have encountered solutions dealing with sed, but those tackle file handling, hence my question.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
jlnkls
  • 123
  • This looks like a XY Problem. If you need the filename only, don't parse the output of ls -l. What is exactly your need? – dr_ Feb 12 '18 at 09:09
  • I have a folder full of tar archives, each one of them containing multiple files. I loop through them as to get a specific file that starts with baz, is followed by some digits and finally with an underscore _. Inside each tar archive there is one such file, for which I want to get the name and output it on a csv file. I get the aforementioned output using the tar command, looking for that specific file, but get that long string, for which I only want the final part. I store that in a variable, and print it then, alongside other information, on a csv file. – jlnkls Feb 12 '18 at 10:09
  • for deleting upto last slash, one can also use basename -- "$myVar" – Sundeep Feb 12 '18 at 10:48

3 Answers3

7

You should use bash Parameter expansion for this and use sub-string removal of type ${PARAMETER##PATTERN}

From the beginning - ${PARAMETER##PATTERN}

This form is to remove the described pattern trying to match it from the beginning of the string. The ## tries to do it with the longest text matching.

Using for your example

$ myVar='-rw-rw-rw- root/root 16 2018-02-12 10:03 foo_tar/baz1234_'
$ echo "${myVar##*/}"
baz1234_

As noted in the comments, the string in question seems to be output of ls command in a variable! which is not an ideal scripting way. Explain your requirement a bit more clearly.

Inian
  • 12,807
  • Thanks, this solution works and does exactly what I wanted. – jlnkls Feb 12 '18 at 10:21
  • I have a folder full of tar archives, each one of them containing multiple files. I loop through them as to get a specific file that starts with baz, is followed by some digits and finally with an underscore _. Inside each tar archive there is one such file, for which I want to get the name and output it on a csv file. I get the aforementioned output using the tar command, looking for that specific file, but get that long string, for which I only want the final part. I store that in a variable, and print it then, alongside other information, on a csv file. – jlnkls Feb 12 '18 at 10:21
1

Awk solution:

myVar='-rw-rw-rw- root/root 16 2018-02-12 10:03 foo_tar/baz1234_'
myVar=$(echo "$myVar" |  awk -F '/' '{print $NF}')

However as others have pointed out, having the output of ls stored as a variable isn't a great idea - if you can provide more context to the script we should be able to advise better solutions

RobotJohnny
  • 1,039
  • 8
  • 18
  • I have a folder full of tar archives, each one of them containing multiple files. I loop through them as to get a specific file that starts with baz, is followed by some digits and finally with an underscore _. Inside each tar archive there is one such file, for which I want to get the name and output it on a csv file. I get the aforementioned output using the tar command, looking for that specific file, but get that long string, for which I only want the final part. I store that in a variable, and print it then, alongside other information, on a csv file. – jlnkls Feb 12 '18 at 10:21
1

From the comments:

I have a folder full of tar archives, each one of them containing multiple files. I loop through them as to get a specific file that starts with baz, is followed by some digits and finally with an underscore _

So is that listing the output of tar tzvf foo.tar.gz or such? My tar outputs only the file names with tar t ... (without v for verbose), so you could just do something like this to get the file name instead of using the shell to process the output line-by-line:

tar tzf foo.tar.gz |grep -E '/baz[0-9]+_$' |sed -e 's,.*/,,'

(or capture it with command substitution: filename=$(tar ... | sed ...) and of course, you can replace the sed with the parameter expansion ${filename##./}.)

ilkkachu
  • 138,973