views:

509

answers:

2

I use ls to obtain my filename which has white space so it looks something like:

my file with whitespace.tar.bz2

I want to pipe this to tar similar to:

ls | grep mysearchstring | tar xvjf

How can I insert double quotes before piping it to tar?

+6  A: 

A good tool for this is find and xargs. For example, you might use:

find . -name '*.tar.bz2' -print0 | xargs -0 -n1 tar xjf
Zan Lynx
find | xargs is the most general, and performant.For pure shell the following will handle whitespaces:for archive in *.tar.bz2; do tar xvjf "$archive"done
pixelbeat
A: 

What's wrong with shell-wildcard expansion? (Assuming there is only one filename.)

% tar -cvf   *mysearchstring*
% tar -xvf   *mysearchstring*

Sure, the filename that matches *mysearchstring* will have spaces. But the shell [tcsh,bash] will assign that filename, including its spaces, to a single argument of tar.

You can verify this with a simple C or C++ program. E.g.:

#include <iostream>
using namespace std;
int main( int argc, char **argv )
{
  cout << "argc = " << argc << endl;
  for ( int i = 0;  i < argc;  i ++ )
    cout << "argv[" << i << "] = \"" << argv[i] << "\"" << endl;
  return 0;
}

Try it: ./a.out *foo*

This is why CSH has the :q [quoted wordlist] option...

E.g. [tcsh]

foreach FILE ( *mysearchstring* )
    tar -xvf $FILE:q
end

Or tar -xvf "$FILE" instead of tar -xvf $FILE:q, if you prefer.


If you really must use ls...

Using ls piped through anything will output one filename per line. Using tr we can translate newlines to any other character, such as null. xargs can receive null terminated strings. This circumvents the spaces problem. Using -n1 will overcome the multiple files problem.

E.g.: \ls | grep mysearchstring | tr '\012' '\0' | xargs --null -n1 tar -xvf

But I don't believe tar accommodates multiple tarfiles from stdin like the OP has it...

Mr.Ree