Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I change lines around using the command line?
e.g. I have these lines:

    Acct-Status-Type = Start
    User-Name = "37XXXXXXX"
    Event-Timestamp = "Apr 12 2013 15:56:55 AMT"

I need to change the order to this:

    Event-Timestamp = "Apr 12 2013 15:56:55 AMT"
    User-Name = "37XXXXXXX"
    Acct-Status-Type = Start

I need to do this by one command, sed, awk, perl or something like that.

share|improve this question
3  
If it is a "first in last out"/reverse of the lines you can use tac. Or sed '1!G;h;$!d' –  Sukminder Apr 13 '13 at 6:46
2  
How exactly do you want to reorder your lines? (sort alphabetically? just reverse the order? something completely different?) - What is the reason for insisting on one single command? (Does something like a perl onliner count as a single command?) –  michas Apr 13 '13 at 7:04
    
sed '1!G;h;$!d' this command helped. also please tell me how to have output by this order: Event-Timestamp = "Apr 12 2013 15:56:55 AMT" Acct-Status-Type = Start User-Name = "37XXXXXXX" –  user37033 Apr 13 '13 at 7:13
1  
Another option: perl -e 'print reverse <>' –  devnull Apr 13 '13 at 10:36
1  
If it is just the reverse, what about sort -r? –  Tom Wijsman Apr 13 '13 at 11:35

2 Answers 2

Depends on where, how often, why etc you do this, but it wouldn't hurt to put it in a script.

Anyhow you could do something like this to print in defined order. By this approach you can also choose to only print a selected few. E.g. only 1 and 3:

One liner:

awk -v order=312 \
'/^/{ln[NR]=$0}END{split(order,a,"");
 for(i in a)printf("%s\n",ln[a[i]]);}' \
 sample.txt

Or more easy to read:

/^/{
    ln[NR] = $0
}
END{
    split(order,a,"");

    for(i in a)
        printf("%s\n",ln[a[i]]);
}

For the split you could add some delimiter if more then 9 lines.

E.g.:

split(order,a,"-");
# and call by:
awk -v order=3-13-21-12-2 ...

Or to support multiple:

if (order ~ /-/)       split(order, a, "-"); # order has "-", split
else if (order ~ /\./) split(order, a, "."); # order has ".", split
else if (order ~/:/)   split(order, a, ":"); # order has ":", split
else                   split(order, a, "");  # none presume numbers split all

You could also choose to match lines as in:

BEGIN {
    i = 0;
}
/^\s*Acct-Status-Type/ {ln[++i] = $0 }
/^\s*User-Name/ {ln[++i] = $0 }
/^\s*Event-Timestamp/ {ln[++i] = $0 }
END {
    if (order ~ /-/)  split(order, a, "-");
    else if (order ~ /\./) split(order, a, ".");
    else if (order ~/:/) split(order, a, ":");
    else split(order, a, "")
    for (i in a)
        printf("%s\n", ln[a[i]]);
}

Edit:

For last sample this would probably be better. (Also updated the split):

/^\s*Acct-Status-Type/ {ln[1] = $0 }
/^\s*User-Name/ {ln[2] = $0 }
/^\s*Event-Timestamp/ {ln[3] = $0 }
END {
    if (split(order, a, "-|:|,| |\\.") == 1) # Space require quoting of arg.
        split(order, a, "")
    for (i in a)
        printf("%s\n", ln[a[i]]);
}
share|improve this answer

With Python and the name of the file as the commandline parameter to the program:

import sys
with open(sys.argv[1]) as fp:
    for line in fp.readlines()[::-1]:
        sys.stdout.write(line)

or writing it back to that file:

import sys
with open(sys.argv[1]) as fp:
    lines = fp.readlines()
with open(sys.argv[1], 'w') as fp:
    for line in lines[::-1]:
        fp.write(line)

or as a filter from stdin to stdout:

lines = sys.stdin.readlines()
for line in lines[::-1]:
    sys.stdout.write(line)
share|improve this answer
    
:/ Fair enough. I edited your post but did not actually change anything so that I could reverse my downvote (you can't change a vote unless a post has been edited). All apologies. –  goldilocks Apr 13 '13 at 11:14
    
@goldilocks No problem. I do like Python and are happy to provide solutions with it, but it is not the only tool for any given job. And I hope when I am overzealous someone corrects me (in which case I will immediately delete the answer) –  Anthon Apr 13 '13 at 12:13
2  
Why Python? How is this better than tac? (Or sort -ro file file for the overwriting version?) –  depquid Apr 13 '13 at 19:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.