Swap words using sed

Hi. I have to swap the first and the third word in all lines of a txt file using sed.
Separators between words are: any charachter, except [a-zA-Z] intervall.
I hope, you'll understand what I want to do. my english is not so good, sorry for that:)

Can you post your sample data?

example:

egy dfdsf ketto sada

-->i need to get the line:

ketto dfdsf egy sada
alma:a korte*szilva narancs

->i need to get the line:

szilva:a korte*alma narancs

I guess the first one is easier. Are there any other separators other than <space> ?

Like in your second line, * : are also considered like that

... couldn't align the words properly...

durden_tyler, your example is correct. I have to get something like that

---------- Post updated at 06:35 PM ---------- Previous update was at 06:20 PM ----------

  • ,: are separators

---------- Post updated at 06:49 PM ---------- Previous update was at 06:35 PM ----------

any charachter is considered separator, except charachters which are between [a-z] or [A-Z]

I'm confused.

You say durden_tyler's example is correct, but there is no example in durden_tyler's posting in this thread.

You said that you want:

, but if all non-alphabetic characters are separators, why shouldn't:

alma:a korte*szilva narancs

be changed to:

korte:a alma*szilva narancs

instead of to:

szilva:a korte*alma narancs

Don,

I had essentially pointed out the same thing as you, but the data in my example didn't show up properly aligned. After a few attempts, I removed it. The OP probably noticed the post while it was still there for a few minutes.

$
$
$ cat f79
egy dfdsf ketto sada
alma:a korte*szilva narancs
$
$ sed 's/^\([a-zA-Z]\+\)\([^a-zA-Z]\+\)\([a-zA-Z]\+\)\([^a-zA-Z]\+\)\([a-zA-Z]\+\)\(.*\)/\5\2\3\4\1\6/' f79
ketto dfdsf egy sada
korte:a alma*szilva narancs
$
$

Although, if the separators are known and the actual words will only consist of "a-zA-Z" (no numbers or underscores, for instance), then you could do something like this -

$
$ sed 's/^\([a-zA-Z]\+\)\([* ,:]\+\)\([a-zA-Z]\+\)\([* ,:]\+\)\([a-zA-Z]\+\)\(.*\)/\5\2\3\4\1\6/' f79
ketto dfdsf egy sada
korte:a alma*szilva narancs
$
$
1 Like

durden_tyler posted an answer, but tis answer was deleted at the time...or I'm not sure about what happened with that.
And sorry, I'm verry tired :frowning: I made a terrible mistake...your version is correct.
so finally : alma:a korteszilva narancs need to be changed to: korte:a almaszilva narancs

thanks for understanding, and again, apologies for my bad english:)

---------- Post updated at 08:39 PM ---------- Previous update was at 08:07 PM ----------

Thank you durden_tyler! Your first example works perfectly!

Applying the specification literally, I'd propoese

$ cat file
korte:a alma*szilva narancs
$ sed -r 's/([[:alpha:]]+)([^[:alpha:]]+)([[:alpha:]]+)([^[:alpha:]]+)([[:alpha:]]+)/\5\2\3\4\1/' file
alma:a korte*szilva narancs

Hoppla - should have read the entire thread - still I think this one will respect locale settings.

1 Like

T720,
Your specification is not clear as to whether empty strings of alphabetic characters constitute a field. (If the first character on a line is not alphabetic, is the 1st field empty? If there are two non-alphabetic characters together, is there an empty field between them?)

The script durden_tyler provided assumes that there are no empty fields and that all sequences of one or more non-alphabetic characters count as a single field separator. (It also assumes that + is a special character in a sed RE acting to specify one or more of the previous RE. Some versions of sed do that, but it is not portable and does not meet the requirements of the POSIX standards and the Single UNIX Specifications.)

The following sed script will do what you want if empty strings are allowed and each non-alphabetic character is to be treated as a separator:

When given the input:

egy dfdsf ketto sada
alma:a korte*szilva narancs
*save3rd remainder
first$second|third\fourth
1x23no change

it produces the output:

ketto dfdsf egy sada
korte:a alma*szilva narancs
rd*save3 remainder
third$second|first\fourth
1x23no change

  1. :alpha: ↩︎

  2. :alpha: ↩︎

1 Like