Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reverse a file in Unix shell

Tags:

bash

shell

unix

I have a file parse.txt

parse.txt contains the following

remo/hello/1.0,remo/hello2/2.0,remo/hello3/3.0,whitney/hello/1.0,julie/hello/2.0,julie/hello/3.0

and I want the output.txt file as (to reverse the order from last to first)using parse.txt

julie/hello/3.0,julie/hello/2.0,whitney/hello/1.0,remo/hello3/3.0,remo/hello2/2.0,remo/hello/1.0

I have tried the following code:

tail -r parse.txt 
like image 892
Rczone Avatar asked Jul 06 '15 18:07

Rczone


People also ask

How do you reverse a file in Linux?

The 'rev' command in Linux, which is available by default, is used to reverse lines in a file or entered as standard input by the user. The command basically searches for endline characters ('\n') which denote the end of a line and then reverse the characters of the line in place.

How do I reverse a shell script?

rev command : It is used to reverse the lines in a file.

What is the reverse command in Linux?

rev command in Linux is used to reverse the lines characterwise. This utility basically reverses the order of the characters in each line by copying the specified files to the standard output. If no files are specified, then the standard input will read. Using rev command on sample file.


2 Answers

You can use the surprisingly helpful tac from GNU Coreutils.

tac -s "," parse.txt > newparse.txt

tac by default will "cat" the file to standard out, reversing the lines. By specifying the separator using the -s flag, you can simply reverse your fields as desired.

(You may need to do a post-processing step to get the commas to work out correctly, which can be another step in your pipeline.)

like image 188
Micah Smith Avatar answered Sep 29 '22 15:09

Micah Smith


I like the tac solution; it's tight and elegant, but as Micah pointed out, tac is part of GNU Coreutils, which means that it's not available by default in FreeBSD, OSX, Solaris, etc.

This can be done in pure bash, no external tools required.

#!/usr/bin/env bash

unset comma
read foo < parse.txt
bar=(${foo//,/ })
for (( count="${#bar[@]}"; --count >= 0; )); do
  printf "%s%s" "$comma" "${bar[$count]}"
  comma=","
done

This obviously only handles one line, per your sample input. You can wrap it in something if you need to handle multiple lines of input.

The logic here is that we can convert the input into an array by replacing commas with spaces. Of course, if our input data included spaces, this would have to be adjusted. Once we have the array, we simply step backwards through it, printing each record.

Note that this does not include a terminating newline. If you want one, you can add it with:

printf '\n'

as a final line.

like image 44
ghoti Avatar answered Sep 29 '22 14:09

ghoti