famedoro
famedoro

Reputation: 1241

Linux Script: substituting a multiple lines with single line of text

What shell script should I use in Linux to replace a group with n lines of text with a single line?

I have a file like :

a
b
c
*
d
e
f
*
g
h
i
*

and I want to get a file as:

abc
def
ghi

Upvotes: 3

Views: 1748

Answers (8)

famedoro
famedoro

Reputation: 1241

Thanks to everybody, I've found this solution which works in case the file is like

field1     2008
field2     703
field3     qeew
field4     80
field5     52
field6     749.11

field1     2009
field2     532
field3     wecwer
field4     82
field5     44
field6     649.97

...

#!/bin/bash

if [ "$1" = "" ]
then
   echo "missing file name"
   exit 1
fi

N=7
i=0
FULL_ROW=""
SAVEIFS=$IFS
if [ -f $1 -a -r $1 ]; then
    LAST_DATA_SCAD=""
    while IFS=$(echo -en "|\n\b") read -ra ROW_RECORD; do

    if [[ "$FULL_ROW" == "" ]]
       then
        FULL_ROW=${ROW_RECORD:11}
       else
        FULL_ROW=$FULL_ROW"|"${ROW_RECORD:11}
    fi
    i=$((i+1))
    if [ $((10#$i)) == $N ]
    then
      echo $FULL_ROW
      FULL_ROW=""
      i=0
    fi
    done < "$1"
   else
     echo "file not found"
   fi
   IFS=$SAVEIFS

Upvotes: 0

cmc
cmc

Reputation: 4413

I believe tr could be considered the correct tool to replace single characters.

tr -d '\n' < file | tr '*' '\n'

Correct in this context would mean most lightweight, least clumsy, least bug-prone, and least cognitively demanding for the purpose. The other solutions work, but tr has the least hidden costs. When you use a lot of small tools as you do in unix, these small advantages really add up over time.

Upvotes: 0

ray
ray

Reputation: 4267

can use awk

awk '{if ($0=="*"){print s;s=""}else{s=s$0}}' file

an bash way to this is

while read x
do
   [ "$x" == "*" ] && echo  || echo -n $x
done < file

Upvotes: 2

Mark Setchell
Mark Setchell

Reputation: 207355

You can do it in the shell without awk, or tr, or anything external too:

#!/bin/bash
while read x
do
   if [ "$x" == "*" ]; then
      echo $line
      line=""
   else
      line="$line$x"
   fi
done

Save as "go", then do:

chmod +x go
./go <inputfile

Upvotes: 0

NTj
NTj

Reputation: 385

If you treat * as the line token, try remove '\n' and replace STAR.

cat <youfile> | tr -d '\n' | tr '*' '\n'

Upvotes: 0

Debaditya
Debaditya

Reputation: 2497

Other than awk solution :

tr '\n' ' ' < Input.txt |sed 's/ //g' | tr '*' '\n'

Upvotes: 1

holgac
holgac

Reputation: 1539

sed way:

sed ':a;N;$!ba;s/\n//g' < t | sed 's:*:\n:g'

t is the file you want to change.

references: How can I replace a newline (\n) using sed? Why does sed not replace all occurrences?

The first command replaces \n with nothing. the second replaces * with \n.

sed is a very powerful stream editor tool by the way, knowing it can help you in more ways than you can imagine.

Upvotes: 2

fedorqui
fedorqui

Reputation: 289495

One awk way:

$ awk '/\*/ {printf "\n"; next} {printf $1}' file
abc
def
ghi
  • In case of *, print a new line. Otherwise, print the character. Using printf, so that new line is not added unless specified.

With xargs:

$ xargs -n4 < file | cut -d' ' -f1-3
a b c
d e f
g h i
  • xargs -n4 < file prints the file in blocks of 4 columns. cut -d' ' -f1-3 prints from 1st to 3rd column.

Upvotes: 0

Related Questions