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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.