0

I want to write a batch script that:

  • Finds a filename
  • The filename is inside a tar archive
  • The tar archive is located in a different directory
  • The filename matches a given pattern

I want to avoid untaring, if possible, and want to store the filename in a variable.

My tar file is located in ./foo_tar, called bar.tar.gz. Inside the tar archive, I want to get the filename of the file starting with baz*, followed by some digits and an underscore (e.g. baz1234_).

So far, I know of the find command, but it does not work when trying to access a tar file. I want something like this:

filename_in_question=$(find ./foo_tar/bar.tar.gz -name 'baz*')

Is there any workaround to this?

  • Does tar ztf ./foo_tar/bar.tar.gz | grep 'baz' do what you need? – JigglyNaga Feb 9 '18 at 11:01
  • Yes, but it does not work when assigning it to a variable filename_in_question (I get qux.sh: 4: qux.sh: ztf: not found) – erik Feb 9 '18 at 11:16
1

Tar can use wildcards itself

tar tzvf ./foo_tar/bar.tar.gz --wildcards '*/baz*'

Eg.:

$ filename_in_question=$(tar tvf test.tar --wildcards '*/received_10205861111464136.mp4')
$ echo $filename_in_question
-rwxr-xr-x ghp/ghp 1931930 2017-11-04 10:36 ./Marieanne/Messenger/received_10205861111464136.mp4
$ echo ${filename_in_question/*\//}
received_10205861111464136.mp4
  • This does unfortunately not work when assigning it to a variable filename_in_question (I get qux.sh: 4: qux.sh: tzvf: not found) – erik Feb 9 '18 at 11:19
  • That is because of an error in your syntax. But I must admit, I'm a stranger to qux.sh. – Gerard H. Pille Feb 9 '18 at 11:21
  • I don't know if we made ourselves clear to you, @tli, but there is a syntax error in your qux.sh script. – Gerard H. Pille Feb 9 '18 at 12:43
  • Yes, thanks for pointing that out. Using filename_in_question=$(tar tzvf ./foo_tar/bar.tar.gz --wildcards '*/baz*') makes it work. This does almost what I want. I end up getting in filename_in_question a string containing more information that just the filename, as it looks something like this: -rw-rw-r-- root/root 81 2018-02-12 10:03 foo_tar/baz1234_ How can I extract only the last part (e.g. baz1234_ in this case)? – erik Feb 12 '18 at 8:27
  • ${filename_in_question/*\//} should give you that, if your fux.sh uses a sensible shell. – Gerard H. Pille Feb 12 '18 at 8:36
0

find only searches files that exist in the directory hierarchy, not those stored inside archives. You can list the files with tar -t:

tar -ztf ./foo_tar/bar.tar.gz --wildcards --no-anchored 'baz*'

--wildcards allows * to be interpreted as a wildcard, and --no-anchored allows the filename to match after any / (so it'll still be found if it's in a subdirectory in the archive).

Pattern-matching in tar is not as flexible as that in find. For the sort of pattern you describe, you could instead filter the complete contents through grep:

tar -ztf ./foo_tar/bar.tar.gz | grep '\(^\|/\)baz[0-9]\+_'

As you want to save the result in a variable, you also need to enclose the command using Command Substitution:

filename_in_question=$(tar -ztf ./foo_tar/bar.tar.gz | grep '\(^\|/\)baz[0-9]\+_')

This would still be necessary if you were using find.

  • This does unfortunately not work when assigning it to a variable filename_in_question (I get qux.sh: 4: qux.sh: -ztf: not found) – erik Feb 9 '18 at 11:20
  • That's a separate problem -- updated. – JigglyNaga Feb 9 '18 at 11:21
  • Thanks for pointing that out - your solution works, but matches more files than the ones I want to retrieve. I expanded the explanation of the specific pattern I am looking for. – erik Feb 12 '18 at 8:33
  • @tli That's easily done by tightening the grep pattern. Updated again. – JigglyNaga Feb 12 '18 at 9:55
0

You need a tar implementation with built-in libfind:

star -t -f ./foo_tar/bar.tar.gz -find -name 'baz*'

will work as you expect and can to a lot more.

Check the schilytools tar ball: http://sourceforge.net/projects/schilytools/files/

star is the oldest free tar implementation. See Man page:

http://schilytools.sourceforge.net/man/man1/star.1.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.