Custom string space manipulation with sed

6

The following command:

head -n 1 $FILE | tail -n 1

Pulls text from line one of $FILE. The format of each line in $FILE is as follows:

1 2 3 4  2 3  3 4 5  4 5 6 7 8 9

As you can see, each character is separated by a single space. Each group is separated by two spaces. Using sed I need to remove the single spaces, and convert the double spaces into single spaces.

The text in $FILE is created by a for loop nested inside another for loop. So the text data on each line is redirected >> to $FILE from the main for loop after the nested has run it's course. Each character/number in the text string is the result of the nested for loop completing once. Then the main for loop sends the nested for loop's output to $FILE.

So an example of pseudo-code would be:

for i in $(seq 1 $RANDOM)
do
    for n in {1..10}
    do
        $do_something
    done

$do_something_else
done >> $FILE

head -n 1 $FILE | tail -n 1 | (sed command here)

How the code above is structured makes no difference to the need here. I simply seek a lightweight method for the text manipulation described above regarding spaces. If this has been asked before, my apologies. I could not find it in my queries.

Yokai

Posted 2016-10-13T11:12:00.083

Reputation: 249

It's not necessary to use tail since head is only giving you one line anyway. – Paused until further notice. – 2016-10-13T19:51:05.287

I determine what is necessary in my scripts. Using tail is merely a failsafe to prevent unwanted activity. In the way I am using head the "1" is actually inside another for loop as well and the line number is determined by $i. The code in the question is just pseudo-code and nothing more. – Yokai – 2016-10-14T05:59:42.970

Answers

6

This should work:

sed 's/ \([^ ]\)/\1/g'

You can also replace the whole last line of the script with this:

sed -n '1s/ \([^ ]\)/\1/gp' "$FILE"

perreal

Posted 2016-10-13T11:12:00.083

Reputation: 663

@Yokai, you don't need the head and tail commands, see the update – perreal – 2016-10-13T12:15:50.500

The method of pulling lines from $FILE is personal preference on my part. – Yokai – 2016-10-14T05:57:50.793

3

How about this:

$ head -n1 $FILE | tail -n 1 | sed 's,  ,|,g' | sed 's, ,,g' | sed 's,|, ,g'
1234 23 345 456789

First we replace all occurrences of double whitespace with | in order to distinguish them from single whitespaces, then we remove all single whitespaces, and finally we replace | with a single whitespace.

Arkadiusz Drabczyk

Posted 2016-10-13T11:12:00.083

Reputation: 1 776

Interesting piping sed into sed twice more. But this happens to do exactly what I asked. Very nice job! – Yokai – 2016-10-13T12:00:53.433

You should be able to do all that in one sed invocation. Keep the initial and final single quotes and replace the bash pipes and "sed"s (not the ones used as dummy characters) with newlines. That turns it into a single, three line sed program. No way to show that in a comment. – Joe – 2016-10-17T23:35:32.197

2

You can do the replacements in a single s command in sed:

s/ \( \?\)/\1/g

To exit after the first line, we can q on line 1. Putting that together:

sed -e 's/ \( \?\)/\1/g' -e '1q'

Toby Speight

Posted 2016-10-13T11:12:00.083

Reputation: 4 090