Pergunta

I found several related questions, but none of them fits what I need, and since I am a real beginner, I can't figure it out.

I have a text file with entries like this, separated by a blank line:

example entry &with/ special characters
next line (any characters)

next %*entry
more words

I would like the output merge the lines, put a comma between, and delete empty lines. I.e., the example should look like this:

example entry &with/ special characters, next line (any characters)
next %*entry, more words

I would prefer sed, because I know it a little bit, but am also happy about any other solution on the linux command line.

Foi útil?

Solução

Improved per Kent's elegant suggestion:

awk 'BEGIN{RS="";FS="\n";OFS=","}{$1=$1}7' file

which allows any number of lines per block, rather than the 2 rigid lines per block I had. Thank you, Kent. Note: The 7 is Kent's trademark... any non-zero expression will cause awk to print the entire record, and he likes 7.

You can do this with awk:

awk 'BEGIN{RS="";FS="\n";OFS=","}{print $1,$2}' file

That sets the record separator to blank lines, the field separator to newlines and the output field separator to a comma.

Output:

example entry &with/ special characters,next line (any characters)
next %*entry,more words

Outras dicas

Simple sed command,

sed ':a;N;$!ba;s/\n/, /g;s/, , /\n/g' file
  • :a;N;$!ba;s/\n/, /g -> According to this answer, this code replaces all the new lines with ,(comma and space).

  • So After running only the first command, the output would be

    example entry &with/ special characters, next line (any characters), , next %*entry, more words
    
  • s/, , /\n/g - > Replacing , , with new line in the above output will give you the desired result.

    example entry &with/ special characters, next line (any characters)
    next %*entry, more words
    

This might work for you (GNU sed):

sed ':a;$!N;/.\n./s/\n/, /;ta;/^[^\n]/P;D' file

Append the next line to the current line and if there are characters either side of the newline substitute the newline with a comma and a space and then repeat. Eventually an empty line or the end-of-file will be reached, then only print the next line if it is not empty.

Another version but a little more sofisticated (allowing for white space in the empty line) would be:

sed ':a;$!N;/^\s*$/M!s/\n/, /;ta;/\`\s*$/M!P;D' file
sed -n '1h;1!H
$ {x
   s/\([^[:cntrl:]]\)\n\([^[:cntrl:]]\)/\1, \2/g
   s/\(\n\)\n\{1,\}/\1/g
   p
   }' YourFile

change all after loading file in buffer. Could be done "on the fly" while reading the file and based on empty line or not.

use -e on GNU sed

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top