Reputation:
I recently come across the following line in a bash script
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' | sed -e '$s/,$/\n/'
input to the first part of pipe is given by another pipe and input is of the form
1,2.3,2.453,23.5345,
Upvotes: 3
Views: 593
Reputation: 203645
NOTE: this is NOT an answer to the posted question so do NOT accept it as such. This is just an awk script posted for comparison with the posted sed script in the question for some additional insight/information.
Assuming @Floris is correct on what he thinks the script does, here's one way to do it with GNU awk. The input file has a couple of lines of data and then 2 blank lines:
$ cat file
1,2.3,2.453,23.5345,
1,2.3,2.453,23.5345,
$
$ gawk -v RS=',\n+$' '{print}' file
1,2.3,2.453,23.5345,
1,2.3,2.453,23.5345
$
In the above RS=',\n+$'
tells awk that there's only 1 record in the whole file and it's everything before the last comma followed by 1 or more newlines. The {print}
prints that record, which could have been done with '1'
as that's a true condition that'd invoke the default action of printing the current record, but I'm trying to emphasize the clarity part of conciseness over brevity in this one since I expect the OP is a newcomer to awk.
Upvotes: 5
Reputation: 46375
Quite the expression. Let's try to pick it apart. The first few commands are
sed -e invokes `sed` with the `-e` flag: "expression follows"
:a a label - can be used with a branch statement (think "goto")
'/\n*$/ any number of carriage returns followed by end of string
{$d;N;ba' delete the last line; next; branch to label a
-e '}' close the bracket
This can really be thought of as the one-line equivalent of a sed script file:
:a # label a
{ # start of group of commands
/\n*$/ # select a line that has carriage returns and then end of string
#(basically empty lines at end of file)
$d; # delete the last line ($ = last line, d = delete)
N; # next
ba # branch to a
} # end of group of commands
at the end of this we have no empty lines left at the input. You can test this with a file that has empty lines at the end - you will find that when you run it through this first part of the script, the empty lines are gone.
Now let's look at the second (easier) bit:
sed -e invoke sed on the output of the previous command
'$s substitute in the last line
/,$/\n/ a comma before the end of the line with a newline
In other words, the whole script seems to do:
Remove all empty lines at the end of the input, then strip the comma at the end of the last line that was not an empty line and replace it with a newline
Upvotes: 6