0

Is it possible in a while loop, on a small file, to save the current line to a variable and check if that variable is included in the next line, if so, delete the next line;

Something like:

while read p ; do
   a gets value of p
   if a included in next line of file, delete next line
done<file

So if we have the lines:

abc man
abc man 13e1312 22
abc 12345
dec asdasfa sadfasfa
dec 22
dec 2232
dec 22 das fss

It will print:

abc man
abc 12345
dec asdasfa sadfasfa
dec 22
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47

3 Answers3

3

Here is a simple script that uses a while loop to read the file line per line and the string contains syntax. It will look if the next line contains the line before at any position because of *"$pre"*. If the line does not contain the line before it will print the line and remember that one as line before.
Change FILENAME with the file name you need.:

#!/bin/sh
pre=
while IFS='' read -r line || [[ -n "$line" ]]; do
   # echo "Line read from file: $line"
   # if line does not contain line pre
   if ! { [ -n "$pre" ] && [[ "$line" == *"$pre"* ]] ; }; then
      # echo "   <$pre> not found!"
      echo "$line"
      pre=$line
   fi
done < "FILENAME"

Output:

abc man
abc 12345
dec asdasfa sadfasfa
dec 22
HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
1
awk '{ dat[NR]=$0 } END { print dat[1];dita=dat[1];for (i=2;i<=NR;i++) { if ( dat[i] !~ dita ) { dita=dat[i];print dita } } }' filename

Broken down:

{ 
 dat[NR]=$0
}
END { 
      print dat[1]
      dita=dat[1]
      for (i=2;i<=NR;i++) {
                          if ( dat[i] !~ dita ) {
                                                  dita=dat[i]
                                                  print dita
                                                }
                          }
    }

Using awk, read all the data into an array and then print the first element of the array (dat) and set the check variable (dita) to the first element. Then loop from the second element to the last checking all data against dita. If there is no pattern match, print the element and set dita to the element just printed.

Raman Sailopal
  • 12,320
  • 2
  • 11
  • 18
1

Try this script

#! /bin/bash
unset previousLine
while IFS='' read -r currentLine; do
    if [ -z ${previousLine+x} ] || ! grep -qF "$previousLine" <<< "$currentLine"; then
        echo "$currentLine"
        previousLine="$currentLine"
    fi
done < file

[ -z ${previousLine+x} ] is true when $previousLine is unset. grep checks if the previous line is part of the current line.

Edit: Andre Kampling and me both came up with the same solution, but he was the first one to answer the question.

Socowi
  • 25,550
  • 3
  • 32
  • 54