Ability to use variable in bash SED - linux

I'm trying to use sed to add a variable prefix to my command...
datestamp="$(date +'%D %r %Z')"
prefix=$("$datestamp site=$i space=$number")
prefix=$("site=$i space=$number")
echo test this thing | sed 's/^/$prefix /'
I'm expecting
site=abc space=12 test this thing

Simply replace the single quotes for the sed line with double quotes, and that should do the trick.
datestamp="$(date +'%D %r %Z')"
prefix="$datestamp site=$i space=$number"
echo test this thing | sed "s#^#$prefix #"

Related

Excluding string from changes in sed

I want to make a sed command to change strings that each comma separated part will be in double quotes. The problem is that some values have already double quotes.
Change from:
ABZ00016,ABZ,"449,9",450,445,449,"-0,21",405,13,"182,15",0,0,0
to
"ABZ00016","ABZ","449,9","450","445","449","-0,21","405","13","182,15","0","0","0"
I prepared two sed commands:
First command excludes values with double quotes
sed -e 's/"[^"]*"//g'
Second adds double quotes to each part
sed -e 's/\([^,]*\),/"\1",/g'
And now I wanted to exclude results from first command and make changes using second command:
sed -e '/"[^"]*"/!s/\([^,]*\),/"\1",/g'
But it doesn't work...
Using gnu-awk you can do this:
awk -v FPAT='"[^"]*"|[^,]*' -v OFS=, '{
for(i=1; i<=NF; i++) {
gsub(/^"|"$/, "", $i)
$i = "\"" $i "\""
}
} 1' file
Output:
"ABZ00016","ABZ","449,9","450","445","449","-0,21","405","13","182,15","0","0","0"
This might work for you (GNU sed):
sed -r 's/^/\n/;:a;s/\n$//;s/\n("[^"]*",?)/\1\n/;s/\n([^,]*)(,?)/"\1"\2\n/;ta' file
Introduce a newline as a marker then: remove the marker when all fields have been processed, skip over quoted fields and surround other fields with quotes. With each substitution advance the marker down the line.
Use sed with regex mate:
sed -r -e 's/[-.a-zA-Z0-9]+/"&"/g' -e 's/""/"/g'
Edit: Updated to Your request, works as expected:
sed -r -e 's/"([^,]+)(,)([0-9]+)"/\1\.\3/g' -e 's/[-.a-zA-Z0-9]+/"&"/g' -e 's/""/"/g' -e 's/\./,/g'

Shell substring with sed in a variable

I have tried this command in bash linux
echo "example=value" | sed "s/^example=\(.*\)$/\1/"
The output is value. But if I put it in a variable, it doesn't work.
For example:
var="example=value" | sed "s/^example=\(.*\)$/\1/"
echo $var
The output is nothing. What wrong?
Do it like this:
var=$(echo example=value | sed "s/^example=\(.*\)$/\1/")
echo $var
assigning a variable doesn't pass the value to sed via pipe.
You can pass while assigning like this:
var="example=value" && echo "$var" | sed "s/^example=\(.*\)$/\1/"
or use a sub shell like this:
var=$(echo "example=value" | sed "s/^example=\(.*\)$/\1/")
You can do this without sed, using shell parameter expansion:
$ var="example=value"
$ var="${var#*=}"
$ echo "$var"
value

bash script to strip out some characters

Bash scripting. How can i get a simple while loop to go through a file with below content and strip out all character from T (including T) using sed
"2012-05-04T10:16:04Z"
"2012-04-05T15:27:40Z"
"2012-03-05T14:58:27Z"
"2011-11-29T15:04:09Z"
"2011-11-16T12:12:00Z"
Thanks
A simple awk command to do this:
awk -F '["T]' '{print $2}' file
2012-05-04
2012-04-05
2012-03-05
2011-11-29
2011-11-16
Through sed,
sed 's/"\|T.*//g' file
"matches double quotes \| or T.* starts from the first T match all the characters upto the last. Replacing the matched characters with an empty string will give you the desired output.
Example:
$ echo '"2012-05-04T10:16:04Z"' | sed 's/"\|T.*//g'
2012-05-04
With bash builtins:
while IFS='T"' read -r a a b; do echo "$a"; done < filename
Output:
2012-05-04
2012-04-05
2012-03-05
2011-11-29
2011-11-16

Sed command giving unexpected result

Below is the shell script I am trying to find the meaning.
sed 's/19984 $/98400 /' | sed 's/19992 $/99200 /'
I expect 19984 $ will get replaced with 98400 and this string will be passed to next sed command which replace 19992 $ with 99200 .
But when I executed the script below with sample input
echo "19984 $ need to be replaced with 98400 "| sed 's/19984 $/98400 /' | sed 's/19992 $/99200 /'
I get the same string
"19984 $ need to be replaced with 98400"
I hope something I am missing here. Please help me. I am new to shell scripts.
Thanks in advance!
For sed, $ is a reserved character to you have to escape it (\$) to be parsed properly:
$ echo "19984 $ need to be replaced with 98400 "| sed 's/19984 \$/98400 /'
98400 need to be replaced with 98400
All together:
$ echo "19984 $ need to be replaced with 98400 "| sed 's/19984 \$/98400 /' | sed 's/19992 \$/99200 /'
98400 need to be replaced with 98400
So you need to keep it like it is.
$ can mean a lot of things:
- a normal character.
- end of line.
- name of a variable.
The way you got the code it means the second case: end of line:
$ echo "19984 " | sed 's/19984 $/98400 /'
98400
$ echo "19984 something" | sed 's/19984 $/98400 /'
19984 something
so sed will match just the cases in which the line ends with 19984. Otherwise it won't match.

linux shell title case

I am wrinting a shell script and have a variable like this: something-that-is-hyphenated.
I need to use it in various points in the script as:
something-that-is-hyphenated, somethingthatishyphenated, SomethingThatIsHyphenated
I have managed to change it to somethingthatishyphenated by stripping out - using sed "s/-//g".
I am sure there is a simpler way, and also, need to know how to get the camel cased version.
Edit: Working function derived from #Michał's answer
function hyphenToCamel {
tr '-' '\n' | awk '{printf "%s%s", toupper(substr($0,1,1)), substr($0,2)}'
}
CAMEL=$(echo something-that-is-hyphenated | hyphenToCamel)
echo $CAMEL
Edit: Finally, a sed one liner thanks to #glenn
echo a-hyphenated-string | sed -E "s/(^|-)([a-z])/\u\2/g"
a GNU sed one-liner
echo something-that-is-hyphenated |
sed -e 's/-\([a-z]\)/\u\1/g' -e 's/^[a-z]/\u&/'
\u in the replacement string is documented in the sed manual.
Pure bashism:
var0=something-that-is-hyphenated
var1=(${var0//-/ })
var2=${var1[*]^}
var3=${var2// /}
echo $var3
SomethingThatIsHyphenated
Line 1 is trivial.
Line 2 is the bashism for replaceAll or 's/-/ /g', wrapped in parens, to build an array.
Line 3 uses ${foo^}, which means uppercase (while ${foo,} would mean 'lowercase' [note, how ^ points up while , points down]) but to operate on every first letter of a word, we address the whole array with ${foo[*]} (or ${foo[#]}, if you would prefer that).
Line 4 is again a replace-all: blank with nothing.
Line 5 is trivial again.
You can define a function:
hypenToCamel() {
tr '-' '\n' | awk '{printf "%s%s", toupper(substr($0,0,1)), substr($0,2)}'
}
CAMEL=$(echo something-that-is-hyphenated | hypenToCamel)
echo $CAMEL
In the shell you are stuck with being messy:
aa="aaa-aaa-bbb-bbb"
echo " $aa" | sed -e 's/--*/ /g' -e 's/ a/A/g' -e 's/ b/B/g' ... -e 's/ *//g'
Note the carefully placed space in the echo and the double space in the last -e.
I leave it as an exercise to complete the code.
In perl it is a bit easier as a one-line shell command:
perl -e 'print map{ $a = ucfirst; $a =~ s/ +//g; $a} split( /-+/, $ARGV[0] ), "\n"' $aa
For the records, here's a pure Bash safe method (that is not subject to pathname expansion)—using Bash≥4:
var0=something-that-is-hyphenated
IFS=- read -r -d '' -a var1 < <(printf '%s\0' "${var0,,}")
printf '%s' "${var1[#]^}"
This (safely) splits the lowercase expansion of var0 at the hyphens, with each split part in array var1. Then we use the ^ parameter expansion to uppercase the first character of the fields of this array, and concatenate them.
If your variable may also contain spaces and you want to act on them too, change IFS=- into IFS='- '.

Resources