2

I am trying to pass output of a command to a variable. Tried many quotes but not successful, please check

I am reading input from a file in $line and processing it, trying to save output in variable a.

set a="$($line|cut -d'-' -f 2|cut -d'.' -f 1|sed 's/[^0-9]*//g’)"

4 Answers 4

2

A few things.

The first is that you shouldn't be using set, that's for shell variables rather than environment variables.

Second, unless $line is an actual command, you need to echo it.

Third, your closing quote on the sed command is the wrong type, instead of '.

So, you should be using:

a="$(echo $line|cut -d'-' -f 2|cut -d'.' -f 1|sed 's/[^0-9]*//g')"

You can see this in action in the following transcript:

pax> line="date=2014.09.05-time=12.34.56"
pax> a="$(echo $line|cut -d'-' -f 2|cut -d'.' -f 1|sed 's/[^0-9]*//g')"
pax> echo $a
12

which grabs the second - delimited field (time=12.34.56), then the first . delimited field from that (time=12), then strips off all non-numerics at the start to give just 12.

Sign up to request clarification or add additional context in comments.

2 Comments

Alternatively, using a here string: cut -d'-' -f 2 <<<"$line".
What's a shell variable? Anyway, set a=42 sets $1 to the literal string a=42, which is certainly not what OP wanted but doesn't seem to me to correspond to the explanation of why it "doesn't work"... Also, it probably should be echo "$line".
1

Use echo

a="$(echo $line|cut -d'-' -f 2|cut -d'.' -f 1|sed 's/[^0-9]*//g')"

Comments

0

Assuming $filename is the name of the file, you're reading from, you're almost there:

a="$(<$filename cut -d'-' -f 2|cut -d'.' -f 1|sed 's/[^0-9]*//g')"

The problems are:

  • Invocation of set, which is not helpful
  • Incorrect reading of the file ($line) executes it, you want to read from it.
  • Wrong quote after //g - you want a simple single quote (') here

1 Comment

Thanks for reply!!! But i want to read $filename line by line... This will work for that too...i m yet to try the code
0

Rather than use a long, multi-process pipeline, use the parameter expansion tools provided by the shell itself.

tmp1=${line#*-}  # Remove everything up to and include the first -
tmp2=${tmp1%%.*} # Remove everything from the first . onward
a=${tmp2//[!0-9]} # Remove anything that isn't a numerical digit

If you are reading from a file, you can fold the first step into the read command itself

while IFS=- read first second rest; do
    tmp=${second%%.*}
    a=${tmp//[!0-9]}
done

It may also be simpler to define a regular expression to capture the part of the string you want (a sample line would help in defining such a regex).

[[ $line =~ $regex ]] && a=${BASH_REMATCH[1]}  # Assuming the first capture group

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.