I want to clean up some files, and make make the way in which they are written more uniform.

So, my input might look something like this:

$a$h$l )r
^9 ^5 l
\ urd

The thing is, some spaces are "unnecessary" and make comparing the files difficult. For this reason, I want to remove all spaces, unless they are positioned directly after one of the following characters:


For example in $<space>, the space should stay.

Or if the space is the second character after one of the following characters:


So for example in iA<space>, the space gets to stay. In iC<space><space>, only the first space gets to stay.

Then there is one more character,


where <space> may follow as either the first or the second character.

However, there's one extra difficulty - in all these cases, the symbols or letters are a command. The characters following them are variables. So $ is a command, and in the case of $$, the first dollar sign is the command, the second is the variable. Because of this, in the case of $$<space>, the space should be deleted even though it follows a $ - because the $ it follows is a variable to the previous $. This is true for all the "commands" in the first list - they are always followed by exactly one variable. Therefore, the same applies to, for example, ^$<space>. The space should be deleted in this case, because the $ is a variable to ^.

The items in the second list, as well as the s in the second list, are always followed by two variables. So, for example ss<space><space> should become ss<space>, as the second s is a variable.

This problem only poses itself with the characters in the first list and with s, as the commands in the second list will never be directly followed up by characters that also pose as commands.

Besides these, there are other commands not listed. However, they're not relevant as they cannot be followed up by space. Space also doesn't pose as a command itself.

I know this is confusing, but I'm happy to clarify any answers you might have.

So, an example-input might be:

$ $ $N
$  $  $a
$$ $^ $i
sa  s l r
*56 l r
o1 o 2
%A% $v

Where the wanted output would be:

$ $ $N
$ $ $a
sa s lr
o1 o 2

I'm using a GNU/Linux operating system.


Sounds easier than your first variant:

perl -pe 's{([\$^\@!/()].|[ios=%]..)| }{$1}g'

Same with GNU sed:

sed -E 's#([$^@!/()].|[ios=%]..)| #\1#g'

Or a portable variant:

sed 's#\(\([$^@!/()].\)*\([ios=%]..\)*\) *#\1#g'
  • sorry. didnt see this. – mikeserv Jan 7 '16 at 15:48

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.