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.

  • It's not necessary to use tail since head is only giving you one line anyway. – Dennis Williamson Oct 13 '16 at 19:51
  • 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 Oct 14 '16 at 5:59
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"
  • @Yokai, you don't need the head and tail commands, see the update – perreal Oct 13 '16 at 12:15
  • The method of pulling lines from $FILE is personal preference on my part. – Yokai Oct 14 '16 at 5:57
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.

  • Interesting piping sed into sed twice more. But this happens to do exactly what I asked. Very nice job! – Yokai Oct 13 '16 at 12:00
  • 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 Oct 17 '16 at 23:35
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'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.