Reputation: 139
I have a file, lets call it 'a.txt' and this file contains the following text line
do to what
I'm wondering what the SED command is to reverse the order of this text to make it look like
what to do
Do I have to do some sort of append? Like append 'do' to 'to' so it would look like
to ++ do (used ++ just to make it clear)
Upvotes: 7
Views: 7186
Reputation: 203
SED:
When you know the exact words you want to exchange:
$ cat a.txt
do to what
$ sed -ri '/do.*what/ s/do/what/' a.txt
$ cat a.txt
what to what
$ sed -ri '/what.*what/ s/what$/do/' a.txt
$ cat a.txt
what to do
But you must know exactly where the words are located, their circumstances, what words surround them, whether they are at the beginning or end of a sentence/line, etc. The right metacharacters to be used will depend on this information.
Upvotes: 0
Reputation: 58371
This might work for you (GNU sed):
sed -r 'G;:a;s/^\n//;t;s/^(\S+|\s+)(.*)\n/\2\n\1/;ta' file
Explanation:
G
add a newline to the end of the pattern space (PS):a
loop name spaces/^\n//;t
when the newline is at the front of the PS, remove it and print lines/^(\S+|\s+)(.*)\n/\2\n\1/;ta
insert either a non-space or a space string directly after the newline and loop to :a
The -r
switch makes the regexp easier-on-the-eye (grouping (...)
, alternation ...|...
and the metacharacter for one-or-more +
are relieved of the need of a backslash prefix).
Alternative:
sed -E 'G;:a;s/^(\S+)(\s*)(.*\n)/\3\2\1/;ta;s/.//' file
N.B. To reverse the line, adapt the above solution to:
sed -E 'G;:a;/^(.)(.*\n)/\2\1/;ta;s/.//' file
Upvotes: 2
Reputation: 70752
As this question was tagged sed, my 1st answer was:
First (using arbitraty _
to mark viewed spaces, when a.txt
contain do to what
:
sed -e '
:a;
s/\([^_]*\) \([^ ]*\)/\2_\1/;
ta;
y/_/ /;
' a.txt
what to do
than, when a.txt
contain do to to what
:
sed -e '
:a;
s/^\(\|.* \)\([^+ ]\+\) \2\([+]*\)\(\| .*\)$/\1\2\3+\4/g;
ta;
:b;
s/\([^_]*\) \([^ ]*\)/\2_\1/;
tb;
y/_/ /;
' <<<'do to to to what'
what to++ do
There is one +
for each supressed duplicated word:
sed -e ':a;s/^\(\|.* \)\([^+ ]\+\) \2\([+]*\)\(\| .*\)$/\1\2\3+\4/g;ta;
:b;s/\([^_]*\) \([^ ]*\)/\2_\1/;tb;
y/_/ /;' <<<'do do to what what what what'
what+++ to do+
But as there is a lot of people searching for simple bash solutions, there is a simple way:
xargs < <(uniq <(tac <(tr \ \\n <<<'do do to what what what what')))
what to do
this could be written:
tr \ \\n <<<'do do to what what what what' | tac | uniq | xargs
what to do
or even with some bash scripting:
revcnt () {
local wrd cnt plut out="";
while read cnt wrd; do
printf -v plus %$((cnt-1))s;
out+=$wrd${plus// /+}\ ;
done < <(uniq -c <(tac <(tr \ \\n )));
echo $out
}
Will do:
revcnt <<<'do do to what what what what'
what+++ to do+
revcnt() {
local out i;
for ((i=$#; i>0; i--))
do
[[ $out =~ ${!i}[+]*$ ]] && out+=+ || out+=\ ${!i};
done;
echo $out
}
where submited string have to be submitted as argument:
revcnt do do to what what what what
what+++ to do+
Or if prossessing standard input (or from file) is required:
revcnt() {
local out i arr;
while read -a arr; do
out=""
for ((i=${#arr[@]}; i--; 1))
do
[[ $out =~ ${arr[i]}[+]*$ ]] && out+=+ || out+=\ ${arr[i]};
done;
echo $out;
done
}
So you can process multiple lines:
revcnt <<eof
do to what
do to to to what
do do to what what what what
eof
what to do
what to++ do
what+++ to do+
Upvotes: 2
Reputation: 18843
As Bernhard said, tac
can be used here:
#!/usr/bin/env bash
set -eu
echo '1 2 3
2 3 4
3 4 5' | while IFS= read -r; do
echo -n "$REPLY " | tac -s' '
echo
done
$ ./1.sh
3 2 1
4 3 2
5 4 3
I believe my example is more helpful.
Upvotes: 0
Reputation: 67211
May be you would like perl for this:
perl -F -lane '@rev=reverse(@F);print "@rev"' your_file
Upvotes: 0
Reputation: 54392
I would use awk
to do this:
awk '{ for (i=NF; i>=1; i--) printf (i!=1) ? $i OFS : $i "\n" }' file.txt
Results:
what to do
EDIT:
If you require a one-liner to modify your file "in-place", try:
{ rm file.txt && awk '{ for (i=NF; i>=1; i--) printf (i!=1) ? $i OFS : $i "\n" }' > file.txt; } < file.txt
Upvotes: 3
Reputation: 3694
I know tac
can do something related
$ cat file
do to what
$ tac -s' ' file
what to do $
Where the -s
defines the separator, which is by default a newline.
Upvotes: 8