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

  • 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. – rexkogitans Oct 20 '19 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 '19 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? – steeldriver Oct 20 '19 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 '19 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 '19 at 13:33
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
  • 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 '19 at 13:14
  • So, the output should look as you want it now. – rexkogitans Oct 20 '19 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 '19 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 '19 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.