5

I know that I can reverse any sentence: echo "a,b,c,d" | rev

but what if I want to reverse only the first part of a sentence, I have tried this:

echo "a,b,c,d Access" | rev

and I get this:

sseccA d,c,b,a, and what I really want is:

d,c,b,a Access

How can I do this?

4
  • 1
    There are a lot of useful answers that will help you in this question: unix.stackexchange.com/questions/132779/… Commented Aug 3, 2014 at 19:44
  • @Networker, Thanks but the answers add a string ".in-addr.arpa" at the end, here I'm already have the string "Access" Commented Aug 3, 2014 at 19:47
  • 4
    So the problem is: given $1 $2 $3...$n, print (rev $1) $2 $3...$n? Commented Aug 3, 2014 at 20:06
  • @Mikel, yes this is it Commented Aug 3, 2014 at 20:09

6 Answers 6

8

One way is to use read to break the line into the first word and the rest, then call rev on only the first word

$ echo "a,b,c,d Access" | { read -r first rest; printf '%s %s\n' "$(rev <<< "$first")" "$rest"; } d,c,b,a Access 
4
  • That assumes the input doesn't contain backslash characters and $first doesn't start with -. Commented Aug 3, 2014 at 20:14
  • Yeah, we can use read -r and printf '%s if necessary. Commented Aug 3, 2014 at 20:17
  • Then why don't we? Why promote a broken command like echo? Commented Aug 3, 2014 at 20:18
  • Done, but untested (not at my computer). Commented Aug 3, 2014 at 20:21
4

With sed:

sed 's/^/ /;:1 s/^\([^ ]*\) \([^ ]\)/\2\1 /;t1 s/ //' 

With perl:

perl -pe 's/\S+/reverse $&/e' 

With zsh:

string='a,b,c,d Access' setopt extendedglob result=${string/(#m)[^ ]#/${(j::)${(Oas::)MATCH}}} 
3

Using pee (pipe tee) from moreutils (apt-get install moreutils):

echo -n "a,b,c,d Access" | pee "cut -d ' ' -f 1 | rev" "cut -d ' ' -f 2" | tr '\n' ' '

The result is d,c,b,a Access with a trailing space, which comes from a translated newline.

5
  • bash: pee: command not found Commented Aug 3, 2014 at 20:05
  • 1
    Try apt-get install moreutils on Debian/Ubuntu or the equivalent on your Linux. Commented Aug 3, 2014 at 20:06
  • I have install pee and have tried the command but it failed: a,b,c,d Access Commented Aug 3, 2014 at 20:10
  • @user79550 Hmm... It works for me - but I had left out the rev in the first version I saved, edited shortly after. Can you check the rev is there? Commented Aug 3, 2014 at 20:12
  • Upvoted because it works for the original question, but take note that it doesn't work for multiple fields (words). Commented Aug 3, 2014 at 20:31
2

Depending on Neven answer:

You can do this using this shell script:

#!/bin/bash secondPart=`echo "a,b,c,d Access" | awk '{print $2} '` firstPart=`echo "a,b,c,d Access" | awk '{print $1} '| awk -F , '{print $4","$3","$2","$1""}'` echo "$firstPart $secondPart" 

in command line just type:

sh yourShellscript.sh 

or using one command line as Jidder suggeted:

awk '$1=gensub(/(.),(.),(.),(.)/,"\\4,\\3,\\2,\\1","g",$1)' <<< "a,b,c,d Access" 
2
  • Thanks but can I do it using one command line Commented Aug 3, 2014 at 20:05
  • @user79550 awk awk '$1=gensub(/(.),(.),(.),(.)/,"\\4,\\3,\\2,\\1","g",$1)' <<< "a,b,c,d Access" Commented Aug 4, 2014 at 10:09
1

A perl solution:

$ echo "a,b,c,d Access" | perl -anle 'print ~~reverse($F[0])," @F[1..$#F]"' d,c,b,a Access 
1

Fair warning: this relies on your commas.

echo "a,b,c,d Access" | tr ,\ '[\n*]' | sed '1!G;$s/\n/,/g;s/\([^,]*\),\(.*\)/\2 \1/p;h;d' 

OUTPUT

d,c,b,a Access 

It's kinda long - longer than it needs to be. It's easier this way:

set -f ; IFS=,\ set -- ${0+a,b,c,d Access} while [ -n "${2+?}" ] do r="$1,$r" shift ; done echo "${r%,} $1" 

OUTPUT

d,c,b,a Access 

Still kinda long, but at least it makes sense. It get's a little easier with a function because you get a shell array. Like:

rev() ( i= set -f ; IFS=$1 ; shift ; set -- $* until [ "$((i=${i:=($#+1)}-1))" -eq 0 ] do [ "$i" -gt 1 ] && s=$IFS || s= eval printf '"%s$s"' \""\$$i"\" done ) rev , a,b,c,d && echo \ Access 

OUTPUT

d,c,b,a Access 

Or if you have it in a variable:

var="a,b,c,d Access" rev , "${var% *}" && echo " ${var##* }" 

OUTPUT

d,c,b,a Access 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.