1

I have a question to this read line. I have in my file n lines. How can I store the value in the line below in the same loop step? Can maybe someone help me with that?

Thank you

Details:

$ cat testfile.txt
1
2
3
4
5
6
7
8
9
10
while read line; do echo "Current line read: $line"; echo "Line below: `grep -A 1 $line testfile.txt`"; done < testfile.txt
Current line read: 1
Line below: 1
2
--
10
Current line read: 2
Line below: 2
3
Current line read: 3
Line below: 3
4
Current line read: 4
Line below: 4
5
Current line read: 5
Line below: 5
6
Current line read: 6
Line below: 6
7
Current line read: 7
Line below: 7
8
Current line read: 8
Line below: 8
9
Current line read: 9
Line below: 9
10
Current line read: 10
Line below: 10
#

grep -A 1 6 testfile.txt 6 7

grep -A 1 6 testfile.txt | grep -v 6 7

5
  • Not at all, and do not use grep within a loop for this. Better use a string variable acting as one-line buffer to hold the value of the line before and turn your algorithm around. Oct 20, 2019 at 11:07
  • Thank you, for your help. Can you make an example of it? I tried to make a variable within the loop, but without the grep, I do not see the way to get this value for this variable.
    – SkaraBrae
    Oct 20, 2019 at 11:14
  • What output do you actually want? 1 and 2, then 2 and 3, 3 and 4, etc. or 1 and 2, then 3 and 4, 5 and 6 and so on? What are you going to do with the lines after? Oct 20, 2019 at 13:18
  • I read these variables out from a temporary file. These different values are used aftewards in a sed, where I output exactly the information between these values from the original file.
    – SkaraBrae
    Oct 20, 2019 at 13:25
  • ... but you are right steeldriver. When I read your question, and the thing I actually want/must do, then it should do 1 and 2, then 3 and 4, then 5 and 6...
    – SkaraBrae
    Oct 20, 2019 at 13:33

1 Answer 1

0

The problem with your solution is that you invoke grep for each line. In fact, grep parses each line, too. So, for a file with n lines, these lines are parsed n^2 times, and loading grep is quite an expensive call.

Use a one-line buffer, in this example called PrevLine, like this:

#!/bin/bash
CurLine=''
isFirstLine=true
while IFS='' read -r LineBelow; do
  if $isFirstLine; then
    echo "This is the first line, so no previous."
  else
    echo "Current line read: ${CurLine}"
    echo "Line below: ${LineBelow}"
  fi
  CurLine="${LineBelow}"
  isFirstLine=false
done <"$1"

In fact, assigning true to isFirstLine is a string assignment, and just mentioning $isFirstLine (in the if-condition) is the execution of the command of this string. Since true and false are bash-builtins, they can be used directly without significant speed impact, but with a high increase of readability.

The last line mentions $1 as input file name, so invoke with:

./test.sh inputfile.txt
4
  • Thank you for your valid answer. Much appreciated. It definetly shows the direction to go. Can you let me know, how to make it the other way around - first line and then the other line. $ ./test.sh testfile.txt Current line: 1 This is the first line, so no previous. Current line: 2 Previous line: 1 Current line: 3 Previous line: 2 Current line: 4 Previous line: 3 ...
    – SkaraBrae
    Oct 20, 2019 at 13:14
  • So, the output should look as you want it now. Oct 20, 2019 at 14:30
  • Again, thank you for your code rexkogitans. It showed how to output two values within the read line. As steelsdriver asked a bit deeper, I told there, that I actually use the values to do later on a sed on another file, where I then extract the content. So, 1 would be the value from and 2 the value unil incl. This means, that I need to have the values in pairs. There are always even numbers in the file, where I read the values out, to build afterwards the sed. I still need to investigate, but your solution helped me further.
    – SkaraBrae
    Oct 20, 2019 at 15:25
  • Rexkogitans - I accepted your answer. I could start from it and do my changes. But it showed as always, that the requirements must be more clear before coding any character. Else it starts in a direction, which can be very expensive. The question from steeldriver was a valid statement. But thanks for your help.
    – SkaraBrae
    Oct 23, 2019 at 9:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .