How do i swap the first word of a line with the last word in a line

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

up vote
0
down vote

favorite

I was trying to replace the first word in a line with the last word in a line using a sed command i=but i can’t seem to figure it out.

share|improve this question

  • In every line, or a specific line. If so which line?
    – Jesse_b
    Nov 28 at 21:29

up vote
0
down vote

favorite

I was trying to replace the first word in a line with the last word in a line using a sed command i=but i can’t seem to figure it out.

share|improve this question

  • In every line, or a specific line. If so which line?
    – Jesse_b
    Nov 28 at 21:29

up vote
0
down vote

favorite

up vote
0
down vote

favorite

I was trying to replace the first word in a line with the last word in a line using a sed command i=but i can’t seem to figure it out.

share|improve this question

I was trying to replace the first word in a line with the last word in a line using a sed command i=but i can’t seem to figure it out.

linux text-processing sed

share|improve this question

share|improve this question

share|improve this question

share|improve this question

edited Nov 28 at 22:12

Jeff Schaller

37.2k1052121

37.2k1052121

asked Nov 28 at 21:28

Navpreet Singh

1

1

  • In every line, or a specific line. If so which line?
    – Jesse_b
    Nov 28 at 21:29

  • In every line, or a specific line. If so which line?
    – Jesse_b
    Nov 28 at 21:29

In every line, or a specific line. If so which line?
– Jesse_b
Nov 28 at 21:29

In every line, or a specific line. If so which line?
– Jesse_b
Nov 28 at 21:29

3 Answers
3

active

oldest

votes

up vote
5
down vote

Using awk:

awk '{ t=$1; $1=$NF; $NF=t; print}'

This will:

  • t=$1 – set t to the first word
  • $1=$NF – set the first word to the last word
  • $NF=t – set the last word to the first word
  • print – print the new line.

$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one

share|improve this answer

  • @Kusalananda: Thanks. Didn’t think of it.
    – Jesse_b
    Nov 28 at 21:41

  • 1

    Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
    – steve
    Nov 28 at 22:37

up vote
4
down vote

Using Perl, and assuming whitespace delimited input and space-delimited output:

perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'

Testure:

$ printf 'Cleanse Fold and Manipulaten' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'
Manipulate Fold and Cleanse

The Perl code, using -a to split the input on whitespace into the array @F, simply swaps the two elements at the start and end of that array before joining the resulting list with spaces, adding a newline at the end.

A shorter Perl variant that matches the first and last words and swaps them in a substitution (this assumes that there are no flanking whitespace in the input though):

perl -pe 's/^(w*)(.*?)(w*)$/$3$2$1/'

The middle bit, .*?, matches the middle of the string non-greedily. We couldn’t have done this this easily with sed as there is no non-greedy modifier like that ? after .*.

share|improve this answer

  • 1

    Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
    – glenn jackman
    Nov 28 at 22:24

up vote
1
down vote

Semi-serious answer: it’s not you, you are fine. The problem is totally in sed‘s s/// command’s verbosity (compare this with the alternative answers):

$ echo "Hello some good world!" |
sed 's/(^[^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+$)/321/'
world! some good Hello

We may also want to swap the first and the last words even if we have space characters before the first and/or after the latter (thanks to comments and other answers):

$ echo "  Hello some   good world!  " |
sed 's/^([[:space:]]*)([^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+)([[:space:]]*)$/14325/'
  world! some   good Hello  

However, these commands use some non-POSIX GNU extensions to the BRE – Basic Regular Expression – syntax (namely, + and |).
A (more portable) command that satisfies the POSIX standard while keeping the convenience of alternation (|) would require Extended regular expressions. For example, using GNU sed with the --posix option (which disables GNU extensions – not actually required):

$ echo "  Hello some   good world!  " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/14325/'
  world! some   good Hello  

Note, however, that POSIX ERE syntax does not include backreferences. This command, too, will require an implementation with extensions to succeed.

share|improve this answer

  • 3

    Will not destroy the original whitespace. +1
    – glenn jackman
    Nov 28 at 22:22

Your Answer

StackExchange.ready(function() {
var channelOptions = {
tags: “”.split(” “),
id: “106”
};
initTagRenderer(“”.split(” “), “”.split(” “), channelOptions);

StackExchange.using(“externalEditor”, function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using(“snippets”, function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: ‘answer’,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: “”,
imageUploader: {
brandingHtml: “Powered by u003ca class=”icon-imgur-white” href=”https://imgur.com/”u003eu003c/au003e”,
contentPolicyHtml: “User contributions licensed under u003ca href=”https://creativecommons.org/licenses/by-sa/3.0/”u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href=”https://stackoverflow.com/legal/content-policy”u003e(content policy)u003c/au003e”,
allowUrls: true
},
onDemand: true,
discardSelector: “.discard-answer”
,immediatelyShowMarkdownHelp:true
});

}
});

draft saved
draft discarded

StackExchange.ready(
function () {
StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f484769%2fhow-do-i-swap-the-first-word-of-a-line-with-the-last-word-in-a-line%23new-answer’, ‘question_page’);
}
);

Post as a guest

Required, but never shown

3 Answers
3

active

oldest

votes

3 Answers
3

active

oldest

votes

active

oldest

votes

active

oldest

votes

up vote
5
down vote

Using awk:

awk '{ t=$1; $1=$NF; $NF=t; print}'

This will:

  • t=$1 – set t to the first word
  • $1=$NF – set the first word to the last word
  • $NF=t – set the last word to the first word
  • print – print the new line.

$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one

share|improve this answer

  • @Kusalananda: Thanks. Didn’t think of it.
    – Jesse_b
    Nov 28 at 21:41

  • 1

    Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
    – steve
    Nov 28 at 22:37

up vote
5
down vote

Using awk:

awk '{ t=$1; $1=$NF; $NF=t; print}'

This will:

  • t=$1 – set t to the first word
  • $1=$NF – set the first word to the last word
  • $NF=t – set the last word to the first word
  • print – print the new line.

$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one

share|improve this answer

  • @Kusalananda: Thanks. Didn’t think of it.
    – Jesse_b
    Nov 28 at 21:41

  • 1

    Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
    – steve
    Nov 28 at 22:37

up vote
5
down vote

up vote
5
down vote

Using awk:

awk '{ t=$1; $1=$NF; $NF=t; print}'

This will:

  • t=$1 – set t to the first word
  • $1=$NF – set the first word to the last word
  • $NF=t – set the last word to the first word
  • print – print the new line.

$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one

share|improve this answer

Using awk:

awk '{ t=$1; $1=$NF; $NF=t; print}'

This will:

  • t=$1 – set t to the first word
  • $1=$NF – set the first word to the last word
  • $NF=t – set the last word to the first word
  • print – print the new line.

$ echo 'one two three four five six' | awk '{ f=$1; l=$NF; $1=l; $NF=f; print}'
six two three four five one

share|improve this answer

share|improve this answer

share|improve this answer

edited Nov 28 at 21:58

answered Nov 28 at 21:37

Jesse_b

11.5k23063

11.5k23063

  • @Kusalananda: Thanks. Didn’t think of it.
    – Jesse_b
    Nov 28 at 21:41

  • 1

    Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
    – steve
    Nov 28 at 22:37

  • @Kusalananda: Thanks. Didn’t think of it.
    – Jesse_b
    Nov 28 at 21:41

  • 1

    Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
    – steve
    Nov 28 at 22:37

@Kusalananda: Thanks. Didn’t think of it.
– Jesse_b
Nov 28 at 21:41

@Kusalananda: Thanks. Didn’t think of it.
– Jesse_b
Nov 28 at 21:41

1

1

Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
– steve
Nov 28 at 22:37

Slightly shorter : awk '{ t=$1; $1=$NF; $NF=t}1'
– steve
Nov 28 at 22:37

up vote
4
down vote

Using Perl, and assuming whitespace delimited input and space-delimited output:

perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'

Testure:

$ printf 'Cleanse Fold and Manipulaten' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'
Manipulate Fold and Cleanse

The Perl code, using -a to split the input on whitespace into the array @F, simply swaps the two elements at the start and end of that array before joining the resulting list with spaces, adding a newline at the end.

A shorter Perl variant that matches the first and last words and swaps them in a substitution (this assumes that there are no flanking whitespace in the input though):

perl -pe 's/^(w*)(.*?)(w*)$/$3$2$1/'

The middle bit, .*?, matches the middle of the string non-greedily. We couldn’t have done this this easily with sed as there is no non-greedy modifier like that ? after .*.

share|improve this answer

  • 1

    Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
    – glenn jackman
    Nov 28 at 22:24

up vote
4
down vote

Using Perl, and assuming whitespace delimited input and space-delimited output:

perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'

Testure:

$ printf 'Cleanse Fold and Manipulaten' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'
Manipulate Fold and Cleanse

The Perl code, using -a to split the input on whitespace into the array @F, simply swaps the two elements at the start and end of that array before joining the resulting list with spaces, adding a newline at the end.

A shorter Perl variant that matches the first and last words and swaps them in a substitution (this assumes that there are no flanking whitespace in the input though):

perl -pe 's/^(w*)(.*?)(w*)$/$3$2$1/'

The middle bit, .*?, matches the middle of the string non-greedily. We couldn’t have done this this easily with sed as there is no non-greedy modifier like that ? after .*.

share|improve this answer

  • 1

    Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
    – glenn jackman
    Nov 28 at 22:24

up vote
4
down vote

up vote
4
down vote

Using Perl, and assuming whitespace delimited input and space-delimited output:

perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'

Testure:

$ printf 'Cleanse Fold and Manipulaten' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'
Manipulate Fold and Cleanse

The Perl code, using -a to split the input on whitespace into the array @F, simply swaps the two elements at the start and end of that array before joining the resulting list with spaces, adding a newline at the end.

A shorter Perl variant that matches the first and last words and swaps them in a substitution (this assumes that there are no flanking whitespace in the input though):

perl -pe 's/^(w*)(.*?)(w*)$/$3$2$1/'

The middle bit, .*?, matches the middle of the string non-greedily. We couldn’t have done this this easily with sed as there is no non-greedy modifier like that ? after .*.

share|improve this answer

Using Perl, and assuming whitespace delimited input and space-delimited output:

perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'

Testure:

$ printf 'Cleanse Fold and Manipulaten' | perl -ape '($F[0],$F[-1])=($F[-1],$F[0]);$_="@Fn"'
Manipulate Fold and Cleanse

The Perl code, using -a to split the input on whitespace into the array @F, simply swaps the two elements at the start and end of that array before joining the resulting list with spaces, adding a newline at the end.

A shorter Perl variant that matches the first and last words and swaps them in a substitution (this assumes that there are no flanking whitespace in the input though):

perl -pe 's/^(w*)(.*?)(w*)$/$3$2$1/'

The middle bit, .*?, matches the middle of the string non-greedily. We couldn’t have done this this easily with sed as there is no non-greedy modifier like that ? after .*.

share|improve this answer

share|improve this answer

share|improve this answer

edited Nov 28 at 22:26

answered Nov 28 at 22:08

Kusalananda

119k16223364

119k16223364

  • 1

    Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
    – glenn jackman
    Nov 28 at 22:24

  • 1

    Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
    – glenn jackman
    Nov 28 at 22:24

1

1

Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
– glenn jackman
Nov 28 at 22:24

Or, allowing for leading trailing whitespace: perl -pe 's/^(s*)(S+)(.+?)(S+)(s*)$/$1$4$3$2$5/' — note the middle bit has at least 1 char to account for separate first/last words.
– glenn jackman
Nov 28 at 22:24

up vote
1
down vote

Semi-serious answer: it’s not you, you are fine. The problem is totally in sed‘s s/// command’s verbosity (compare this with the alternative answers):

$ echo "Hello some good world!" |
sed 's/(^[^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+$)/321/'
world! some good Hello

We may also want to swap the first and the last words even if we have space characters before the first and/or after the latter (thanks to comments and other answers):

$ echo "  Hello some   good world!  " |
sed 's/^([[:space:]]*)([^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+)([[:space:]]*)$/14325/'
  world! some   good Hello  

However, these commands use some non-POSIX GNU extensions to the BRE – Basic Regular Expression – syntax (namely, + and |).
A (more portable) command that satisfies the POSIX standard while keeping the convenience of alternation (|) would require Extended regular expressions. For example, using GNU sed with the --posix option (which disables GNU extensions – not actually required):

$ echo "  Hello some   good world!  " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/14325/'
  world! some   good Hello  

Note, however, that POSIX ERE syntax does not include backreferences. This command, too, will require an implementation with extensions to succeed.

share|improve this answer

  • 3

    Will not destroy the original whitespace. +1
    – glenn jackman
    Nov 28 at 22:22

up vote
1
down vote

Semi-serious answer: it’s not you, you are fine. The problem is totally in sed‘s s/// command’s verbosity (compare this with the alternative answers):

$ echo "Hello some good world!" |
sed 's/(^[^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+$)/321/'
world! some good Hello

We may also want to swap the first and the last words even if we have space characters before the first and/or after the latter (thanks to comments and other answers):

$ echo "  Hello some   good world!  " |
sed 's/^([[:space:]]*)([^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+)([[:space:]]*)$/14325/'
  world! some   good Hello  

However, these commands use some non-POSIX GNU extensions to the BRE – Basic Regular Expression – syntax (namely, + and |).
A (more portable) command that satisfies the POSIX standard while keeping the convenience of alternation (|) would require Extended regular expressions. For example, using GNU sed with the --posix option (which disables GNU extensions – not actually required):

$ echo "  Hello some   good world!  " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/14325/'
  world! some   good Hello  

Note, however, that POSIX ERE syntax does not include backreferences. This command, too, will require an implementation with extensions to succeed.

share|improve this answer

  • 3

    Will not destroy the original whitespace. +1
    – glenn jackman
    Nov 28 at 22:22

up vote
1
down vote

up vote
1
down vote

Semi-serious answer: it’s not you, you are fine. The problem is totally in sed‘s s/// command’s verbosity (compare this with the alternative answers):

$ echo "Hello some good world!" |
sed 's/(^[^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+$)/321/'
world! some good Hello

We may also want to swap the first and the last words even if we have space characters before the first and/or after the latter (thanks to comments and other answers):

$ echo "  Hello some   good world!  " |
sed 's/^([[:space:]]*)([^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+)([[:space:]]*)$/14325/'
  world! some   good Hello  

However, these commands use some non-POSIX GNU extensions to the BRE – Basic Regular Expression – syntax (namely, + and |).
A (more portable) command that satisfies the POSIX standard while keeping the convenience of alternation (|) would require Extended regular expressions. For example, using GNU sed with the --posix option (which disables GNU extensions – not actually required):

$ echo "  Hello some   good world!  " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/14325/'
  world! some   good Hello  

Note, however, that POSIX ERE syntax does not include backreferences. This command, too, will require an implementation with extensions to succeed.

share|improve this answer

Semi-serious answer: it’s not you, you are fine. The problem is totally in sed‘s s/// command’s verbosity (compare this with the alternative answers):

$ echo "Hello some good world!" |
sed 's/(^[^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+$)/321/'
world! some good Hello

We may also want to swap the first and the last words even if we have space characters before the first and/or after the latter (thanks to comments and other answers):

$ echo "  Hello some   good world!  " |
sed 's/^([[:space:]]*)([^[:space:]]+)([[:space:]].*[[:space:]]|[[:space:]]+)([^[:space:]]+)([[:space:]]*)$/14325/'
  world! some   good Hello  

However, these commands use some non-POSIX GNU extensions to the BRE – Basic Regular Expression – syntax (namely, + and |).
A (more portable) command that satisfies the POSIX standard while keeping the convenience of alternation (|) would require Extended regular expressions. For example, using GNU sed with the --posix option (which disables GNU extensions – not actually required):

$ echo "  Hello some   good world!  " |
sed --posix -E 's/^([[:space:]]*)([^[:space:]]{1,})([[:space:]].*[[:space:]]|[[:space:]]{1,})([^[:space:]]{1,})([[:space:]]*)$/14325/'
  world! some   good Hello  

Note, however, that POSIX ERE syntax does not include backreferences. This command, too, will require an implementation with extensions to succeed.

share|improve this answer

share|improve this answer

share|improve this answer

edited 2 days ago

answered Nov 28 at 22:05

fra-san

1,106214

1,106214

  • 3

    Will not destroy the original whitespace. +1
    – glenn jackman
    Nov 28 at 22:22

  • 3

    Will not destroy the original whitespace. +1
    – glenn jackman
    Nov 28 at 22:22

3

3

Will not destroy the original whitespace. +1
– glenn jackman
Nov 28 at 22:22

Will not destroy the original whitespace. +1
– glenn jackman
Nov 28 at 22:22

draft saved
draft discarded

Thanks for contributing an answer to Unix & Linux Stack Exchange!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

Please pay close attention to the following guidance:

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

draft saved

draft discarded

StackExchange.ready(
function () {
StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f484769%2fhow-do-i-swap-the-first-word-of-a-line-with-the-last-word-in-a-line%23new-answer’, ‘question_page’);
}
);

Post as a guest

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Required, but never shown

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *