1

Say I have a string as name = xyz here after name there is a tab and after '=' there are random number of spaces.

I need an output as name=xyz

So how can I remove both tabs and random number of spaces from the above mentioned string using sed or awk and tcl regsub function. Help is highly appreciated. Thanks.

I tried

[regsub -all { +} $str ""]

This removes the random number of spaces from $str but tabs are still present.

markalex
  • 8,623
  • 2
  • 7
  • 32
  • 2
    Even though the `tr` command wasn't one of your mentioned options, it may be the simplest way to solve the problem if you have that option. Piping the input through `tr -d '[:blank:]'` will remove all of the white space (including repeated characters) while preserving newlines and linefeeds. – radical7 Apr 12 '23 at 05:58

6 Answers6

5

\s matches both tab character and whitespace. Then would you please try:

[regsub -all {\s+} $str ""]

The potential problem here is it will remove blank characters anywhere regardless of the relevance to the = sign.

It will be safer to say:

[regsub {\t=\s*} $str "="]

which removes a tab character before = and whitespace(s) after =.

tshiono
  • 21,248
  • 2
  • 14
  • 22
  • 1
    A bit simpler: `regsub {\s*=\s*} $str "="` -- no need to capture anything. – glenn jackman Apr 12 '23 at 14:08
  • Additionally, if there's a weird line like `set str "name\t= foo\t\t= bar"`, your regex will replace the **last** = (due to the greedy initial `.+`) while mine will replace the **first** one. – glenn jackman Apr 12 '23 at 14:11
  • @glennjackman thank you for the suggestion. I've updated the answer accordingly. – tshiono Apr 12 '23 at 23:37
  • Thanks for the input, worked like a charm and was also easy to understand. – Himanshu_Pandey Apr 14 '23 at 00:36
  • Thank you for the feedback. Good to know it works. If you feel my answer solves well your problem, I'd appreciate if you can accept my answer by clicking on the check mark beside the answer. BR. – tshiono Apr 14 '23 at 01:08
2

Here is also solution using sed

myvar=$(sed -E 's/\s*=\s*/=/g' <<<$myvar)

or, to be more portable you can use [[:space:]] instead of \s

myvar=$(sed -E 's/[[:space:]]*=[[:space:]]*/=/g' <<<$myvar)

Here every occurrence of = surrounded by any number of whitespace symbols will be replaces with just =, without any whitespaces.

markalex
  • 8,623
  • 2
  • 7
  • 32
2

Using bash parameter substitution:

$ str='name    = xyz'
$ str="${str//[ \t]/}"
$ echo "$str"
name=xyz

# or

$ str='name    = xyz'
$ str="${str//[[:space:]]/}"
$ echo "$str"
name=xyz
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
1

This question has received much of an attention, surprisingly. So, I throw in my take on the task. In Tcl, rather than using regsub, you may use the internal list parser to throw away the separating characters:

join [list {*}$str] ""

This certainly depends on whether you fully control the input string. It needs to conform to a valid string representation of a Tcl list.

mrcalvin
  • 3,291
  • 12
  • 18
0

I would harness GNU AWK for this task following way

echo "name    = xyz" | awk 'BEGIN{OFS=""}{$1=$1;print}'

gives output

name=xyz

Explanation: GNU AWK assumes field separator is one-or-more whitespace character which is compliant with your use case, I set OFS to empty string so there will be nothing between fields, $1=$1 triggers string rebuild, print does print it. If you want to know more about OFS then read 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

(tested in GNU Awk 5.0.1)

Daweo
  • 31,313
  • 3
  • 12
  • 25
-1

Another solution with awk:

echo 'name    = xyz' | awk NF++ OFS=

Results in

name=xyz
General Grievance
  • 4,555
  • 31
  • 31
  • 45
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11
  • 1
    Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes. – Mark Rotteveel Apr 13 '23 at 10:18
  • @MarkRotteveel : just the post below mine already has a link to explaining what `NF` and `OFS` are for. you want me to duplicate that ? or do i need to explain `++` as well ? In fact, my solution is the least verbose way to express what Daweo said below, with a very subtle difference - mine skips blank lines, hers/his/its version would print those out. @General Grievance : it's just my styling preference to clearly delineate the test input and resulting output sections from the code itself. – RARE Kpop Manifesto Apr 13 '23 at 14:06
  • Yes, you should make your answer as complete as possible with sufficient information to understand your solution. – Mark Rotteveel Apr 13 '23 at 14:21
  • @MarkRotteveel : define sufficient. can i assume they have a minimal understanding of what `stdin` means, or do i need to include a unix tutorial as well ? – RARE Kpop Manifesto Apr 15 '23 at 00:12
  • 1
    Please read [this](https://meta.stackoverflow.com/a/417272/) before rolling back again. – General Grievance Apr 15 '23 at 00:48
  • @GeneralGrievance : and yet my original layout visually delineated input, code, and output, such that redundant verbosity like "Results in" aren't necessary. You're welcomed to treat other people your own way, but don't libel and slander me by applying those condescending and patronizing section headers as if it came out of my mouth. Probably need to put obi-wan back on my speed dial again – RARE Kpop Manifesto Apr 15 '23 at 08:27
  • 1
    You visually delineated code *incorrectly*. When you use the blockquote, you are saying that another source has said it, see [referencing guidelines](https://stackoverflow.com/help/referencing). Since that *wasn't* the intention, an edit to remove that was justified. There are many valid options on the table for doing what you intended, I just offered one. You are more than welcome to edit too. Just don't misuse formatting. – General Grievance Apr 15 '23 at 20:28