1

I have a file which contains lots of records in following manner.

Name Address Phone 

This is the sequence for each record in that file. Now, I want to copy this file to other file with changed order as below.

Address Phone Name 

How to write shell script to do this?

2
  • what is the delimiter between records? Commented May 9, 2015 at 14:09
  • They are line by line Commented May 9, 2015 at 14:11

4 Answers 4

4

Try:

sed -n 'h;n;p;n;G;p' < file.in > file.out 

For example:

$ seq 9 | sed -n 'h;n;p;n;G;p' 2 3 1 5 6 4 8 9 7 
5
  • Thanks Stephane. It's working fine for single record in the file, but getting different output than expected if I have multiple records in file. Commented May 9, 2015 at 14:32
  • OK, sorry, see edit. Commented May 9, 2015 at 14:38
  • It's perfect now. Commented May 9, 2015 at 14:41
  • Terrific! Can you please explain what's going on there (what does the character sequence mean)? Commented May 9, 2015 at 18:53
  • @try-catch-finally, hold next print next get print Commented May 9, 2015 at 21:18
2

If I'm reading your question right, you want to take sequences of 3 lines from the file, and swap the order of the first and last in each? With GNU sed, you could do something like this I think:

sed -e :a -e '$!N' -e 's/\(.*\)\n\(.*\)\n\(.*\)$/\2\n\3\n\1/;Ta' file 

which continually slurps up lines until it is able to make the swap, and then starts over.

2
  • @shinek ... well let's wait to see what the sed gurus have to say, I'm sure to have made a boo-boo somewhere ;) Commented May 9, 2015 at 14:37
  • You could use first~step to golf it shorter: sed '1~3{h;d};3~3G' Commented May 9, 2015 at 17:39
1

With awk:

awk '{l=$0;getline;print;getline;print $0"\n"l;}' < file_in > file_out 

Explanation:

  1. Save current record in variable l

  2. Get next record using getline

  3. Print that record (print, invoked without arguments will always print the current record)

  4. Get the next record again using getline

  5. Print that record, a newline and the first record stored in l

  6. For the next record(s) start over at 1.

References

0

For some one-liner transformations, I like to use pyp (distributed as "pypyp").

Unlabeled lines

If your lines are not labelled, you can do an unconditional transformation like so (%3: 0->2 1->0 2->1):

  • $ seq 9 | pyp '[elem for group in zip(lines[1::3],lines[2::3],lines[0::3]) for elem in group]'

Shorter example output looks like this:

$ seq 6 | pyp '[elem for group in zip(lines[0::3],lines[2::3],lines[1::3]) for elem in group]' 1 3 2 4 6 5 

Labeled lines

Data setup:

$ pyp -b 'faker.Faker.seed(202418);f=faker.Faker()' \ 'json.dumps( [dict(name=f.first_name(), address=f.address().replace("\n",", "), phone=f.phone_number()) for i in range(2)])' \ | jq '.[]|to_entries[]|(.key + ": " + .value)' -r \ | tee q202418.data 

Parsing by prefix, not as robust as parsing into records:

$ <q202418.data \ pyp -b 'f=lambda categ: filter(lambda l: l.startswith(categ), lines)' \ 'names=f("name:"); addrs=f("address:"); ps=f("phone:"); [line for group in zip(addrs, ps, names) for line in group]' 

For a discussion of more robust multi-line record parsing, see https://stackoverflow.com/questions/13295083/parsing-a-multi-line-data-file-with-python.

Other pyp notes

pyp's --explain flag can help show what's happening, or allow you to save it as a standalone script:

$ seq 9 | pyp --explain '[elem for group in zip(lines[1::3],lines[2::3],lines[0::3]) for elem in group]' #!/usr/bin/env python3 import sys from pyp import pypprint lines = [x.rstrip('\n') for x in sys.stdin] output = [elem for group in zip(lines[1::3], lines[2::3], lines[0::3]) for elem in group] if output is not None: pypprint(output) 

Pyp supports customization through a PYP_CONFIG_FILE.

pyp performs static analysis of the input code, some AST transformations and pruning, then compiles and executes the result, or with --explain, unparses the AST back to source. It imports packages from its environment, and errors early on unknown or undefined symbols.

See other usage examples at https://pypi.org/project/pypyp/.

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.