1

I am having issues with deleting the line from a file. My program will check for a particular condition using while and if loop and if it matches then delete the line from the file. But while deleting I am getting the error like " sed: can't read". I think I am near to the solution but unable to get sort it out. Below is the code I am using.

#!/bin/ksh

File='dsgp_p50.dat'
cd /home/lpadmin
while read -r line
do
x=`echo "$line" | cut -c 75-104`
echo $x
if [ $x == '00000000000000+00000000000000+' ]
then
sed '1,1d' "$line" > vikas.dat
fi
done < $File

UPDATED:

I have a file which contains data in the below form.

507425B30    171013D248900022   4057-ACCR PROPERTY TAX  
00000000257910+00000000000000+00000000257910+00000000000000+00000000000000+
507425B30    171013C249999092   1071-DO NOT USE         
00000000000000+00000000000000+00000000000000+00000000031940+00000000000000+

Now i have to delete the lines which contains the pattern like 00000000000000+00000000000000+ ( The position of this pattern in the file is 75-104) and the tricky part is that we have to delete the line only when it comes in the 1st occurrence in the same line. There will be scenarios like the first record in the above where the pattern came at the last and it should not delete the line from the file. It should delete the line only when the pattern 00000000000000+00000000000000+ comes in the position 75-104.

  • 1
    Hi Don. The file contains the pattern "00000000000000+00000000000000+" sometimes twice in the same line. I need to capture the pattern that comes at the first instance in the line and then delete it. I tried using Sed to fix this but it is still deleting the line even when the pattern comes in the second instance in the same line which it shouldn't do.... – Ravi Rock Oct 25 '17 at 11:57
  • Hi Don. I have edited the post with more information. – Ravi Rock Oct 25 '17 at 12:04
  • 1
    How big is this data file? It's generally not a good idea to use read to process files like that. Firstly, it's really inefficient: read makes a system call for each character that it reads, so it's slow. But there are various other reasons to avoid it. Please see Why is using a shell loop to process text considered bad practice? for details. – PM 2Ring Oct 25 '17 at 12:50
  • When you mention "position" do you mean "line in the file" or "position on the line"? Do you only want to delete the lines with the long strings of zeroes, or the preceding line as well? It is also unclear what the output should actually look like and why. Please edit your question to clarify. – Kusalananda Oct 27 '17 at 8:38
2

Some sed hints for you:

  1. It almost never makes sense to do a while read loop over a file and use sed or awk inside, as those tools are designed to process a file line by line anyhow

  2. The address range in sed '1,1d' is superfluous. If you want to address a single line, you can do sed '1d' without range. In this case, there is only one line anyhow, so why redirect a deleted line to a file?

  3. In sed '1,1d' "$line", $line is expected to be the filename!

  4. So what you should do is a simple sed '/find the right regexp/d' $File.

  5. The pattern to match the given string at position 75ff in the line would be /^.\{74\}00000000000000+00000000000000+/ (that's the start of the line (^), followed by 74 random chars and the pattern.

  6. As in the point above the \{number\} gives a number of repeated items, you can simplify to /^.\{74\}0\{14\}+0\{14\}+/

  7. Now you can further simplify by grouping the repeated sequence: \(sequence\)\{2\)

Now using extended regular expressions to avoid the backslash escaping, your whole script can be replaced by a simple

sed -E '/^.{74}(0{14}\+){2}/d' $File

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.