1

Once i execute | xxd -bi, I get the output as

00000000: 01101000 01100101 01101100 01101100 01101111 00001010 hello.

Now I am trying to remove initial 0000000, which I did using sed and I am trying to remove "hello" (variable text) which is stored in $covertthis using sed but I can't achieve so, as shown below in the example please suggest me the changes.

I have tried using cut aswell but can't alter both 0000000 and last variable word.

echo "What you want to input numbers or string?"
read input

if [[ "$input" == "number" ]] || [[ "$input" == "Number" ]] || [[ "$input" == "NUMBER" ]] ;then
        echo "Number selected 1"
elif [[ "$input" == "String" ]] | [[ "$input" == "STRING" ]] || [[ "$input" == "string" ]] ;then
        echo "String selected"
        echo "Please give me the string to be XOR'ed"
        read convertthis
        echo  $convertthis | xxd -bi > bin-store
        $(sed -i -e 's/00000000://g' bin-store)
        $(sed -i -e 's/($convertthis).//g' bin-store)
else
        echo "Please re-run the script, input is wrong"
fi
Cyrus
  • 84,225
  • 14
  • 89
  • 153

4 Answers4

3

You need only one sed for that. Separate commands using ;

# read convert_this
echo "00000000: 01101000 01100101 01101100 01101100 01101111 00001010  hello." | 
sed -E "s/^[^[:blank:]]*[[:blank:]]+//;s/[[:blank:]]+$convert_this\.$//" 

should do it.

Output

01101000 01100101 01101100 01101100 01101111 00001010

Explanation

  • The -E option with sed enables the use of Extended regular expressions.
  • s/^[^[:blank:]]*[[:blank:]]+//; The ^ in the beginning looks for the start of the line. [] in sed is meant for ranges. If the range begins with a ^ that means you're negating a range. The * looks is meant for zero or more and + is meant for one or more. The [:blank:] is a character class matching any blank characters like whitespaces tabs and so. In short we are looking for any non-blank characters in the beginning followed by one or more spaces. Then we substitute it with nothing effectively deleting it.
  • The second substitute replaces the string stored in $convert_this and any full-stop that follows with nothing.

All good :-)


Sidenote: You need to use double quotes to wrap the sed commands so that your bash variables are expanded.

sjsam
  • 21,411
  • 5
  • 55
  • 102
  • Can't seem to make it work, little explanation would be great. – Saubhagya Srivastava Jan 21 '18 at 10:41
  • @SaubhagyaSrivastava : See the edit. I'll put an explanation soon. – sjsam Jan 21 '18 at 10:43
  • The command above will work only on a single word what to do if i want to go for removing entire string? @sjsam – Saubhagya Srivastava Jan 21 '18 at 10:46
  • 1
    @sjsam: the last quote of your sed command by a double quote. `sed -E "s/^[^[:blank:]]*[[:blank:]]+//;s/$convert_this//"` :-) – Allan Jan 21 '18 at 11:02
  • 1
    @SaubhagyaSrivastava Please note I have accidentally put a single quote at the end as mentioned in the above comment. Hope you have already sorted that out. \@Allan Thankyou.. Changed. – sjsam Jan 21 '18 at 11:04
  • `echo "00000000: 01101000 01100101 01101100 01101100 01101111 00001010 hello." | sed -E "s/^[^[:blank:]]*[[:blank:]]+//;s/$convert_this//"` Output :`01100101 01101100 01101100 01101111 00001010 hello.` What's wrong with the above? – Saubhagya Srivastava Jan 21 '18 at 11:07
  • @SaubhagyaSrivastava If you are getting hello at the end, then the `-E` option is not defined for your `sed`. Replace it with `-r`. – sjsam Jan 21 '18 at 11:10
  • @sjsam `sed -E -i "s/^[^[:blank:]]*[[:blank:]]+//;s/$convert_this//" bin-store);` this works but gives a `.` full stop at the end – Saubhagya Srivastava Jan 21 '18 at 11:12
  • Is the string that you're trying to remove always at the end? @SaubhagyaSrivastava – sjsam Jan 21 '18 at 11:16
  • @SaubhagyaSrivastava Great news. I have edited my post accordingly. Anyways I feel the [first solution](https://stackoverflow.com/revisions/48365865/2) that I posted was the most suitable for you. That would have removed any string at the end. – sjsam Jan 21 '18 at 11:21
  • @SaubhagyaSrivastava Do confirm that it is working or not – sjsam Jan 21 '18 at 11:27
  • 1
    @sjsam The older code you posted which removes the last word works :) – Saubhagya Srivastava Jan 21 '18 at 12:59
2

Following awk may also help you in same.

awk -v val="hello." '{sub(/^0+: +/,"");sub(val,"")} 1'   Input_file

Or if you have a shell variable which we want to pass to awk command then following may help you too:

convertthis="hello."
awk -v val="$convertthis" '{sub(/^0+: +/,"");sub(val,"")} 1'   Input_file

Output will be as follows.

01101000 01100101 01101100 01101100 01101111 00001010
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • This would be limited to `hello.`, I think can I employ the same using a variable? in place of `hello` – Saubhagya Srivastava Jan 21 '18 at 11:20
  • @SaubhagyaSrivastava, yes please `hello` value is not hardcoded, in `awk` variables are defined by `-v` which I had defined by using `-v val`, so change the value of `val=` and it should fly for other values too, let me know if you have any queries on same. – RavinderSingh13 Jan 21 '18 at 11:22
  • @SaubhagyaSrivastava, also please check my OR solution which will have shell variable's value into awk variable and you could have any value in it and could change any string from it too. – RavinderSingh13 Jan 21 '18 at 11:24
1

Use

sed -i -e "s/$convertthis.$//" bin-store 

instead of

$(sed -i -e 's/($convertthis).//g' bin-store)

to use the content of your convertthis variable instead of its literal name

Allan
  • 12,117
  • 3
  • 27
  • 51
0

Try this command:

sed "s/\(^[0-9a-z]\{8\}:[[:space:]]\)\([^a-z]*\)\([a-z]*\)/\2/"

The regex splits the input into three group matches; the groups are delineated using escaped brackets \( \). The groups are as follows:

  1. The first group is alphanumeric and 8 characters, prepended by a colon and a space. We have ^ to match the beginning then and 8 alphanumeric characters matched by [0-9a-z]\{8\}: in this expression the square braces enclose a character class (alphanumeric). The space can be matched by [[:space:]].

  2. The second group contains no alphabetic characters which we match as [^a-z]* where the ^ inverts the match in square braces.

  3. The third group matches the alphabetic characters at the end.

We can then replace the string by any of the three groups: group 2 (\2) is the one that we want.

This works just as well for multi-line input as sed matches line by line.


Side note : for POSIX compliance to match spaces [[:space:]] should be used not \s (see this question).

David
  • 306
  • 1
  • 7