Cody Glickman
Cody Glickman

Reputation: 524

Remove last character of every nth line in place

I have a file with four repeated lines. I am looking to remove the last character of every fourth line. A description of the file is below.

@Header  
DNA Sequence 
+ 
Quality score!
<Pattern of four above lines repeats>

I am trying to remove the last character (an exclamation point) from every fourth Quality score line.

@Header  
DNA Sequence 
+ 
Quality score
<Pattern of four above lines repeats>

I am able to use awk to pull out every fourth line, but how do I remove the last character in place on every fourth line of the file?

This question operates only on a specific line. Currently my approach is to use awk to pull the Quality score and I can remove the last character with sed.

awk 'NR == 4 || NR % 4 == 0'
sed 's/.$//'

I am currently not sure how to overwrite the edited Quality scores into the original file. Any thoughts or more concise inplace sed / awk arguments would be appreciated.

Upvotes: 3

Views: 887

Answers (5)

potong
potong

Reputation: 58351

This might work for you (GNU sed):

sed 'n;n;n;s/.$//' file

Or

sed 'N;N;N;s/.$//' file

Upvotes: 0

dawg
dawg

Reputation: 103704

Given:

$ cat file
1!
2!
3!
4!
5!
6!
7!
8!
9!
10!
11!
12!

You can use awk:

$ awk 'NR%4==0{sub(/!$/,"")}1' file
1!
2!
3!
4
5!
6!
7!
8
9!
10!
11!
12

And if you have gawk you can change in place:

$ gawk -i inplace 'NR%4==0{sub(/!$/,"")}1' file
$ cat file
1!
2!
3!
4
5!
6!
7!
8
9!
10!
11!
12

If you only have POSIX awk, you can effectively get an inplace replacement by using a temp file:

$ awk 'NR%4==0{sub(/!$/,"")}1' file >tmp_file && mv tmp_file file

(Which is what GNU sed or GNU awk or perl or ruby is doing under the covers anyway with 'inplace' replacement...)

Upvotes: 3

choroba
choroba

Reputation: 241758

Perl to the rescue!

perl -lpe 'chop if 0 == $. % 4'
  • -p reads the input line by line and prints it after processing
  • -l removes a newline from the input line and adds it back to output
  • chop removes the last character
  • $. is a special perlvar that contains the input line number, % is the modulo operator

Upvotes: 3

RavinderSingh13
RavinderSingh13

Reputation: 133428

Could you please try following.

awk 'FNR%4==0{print substr($0,1,length($0)-1);next} 1' Input_file > temp_file && mv temp_file Input_file

This will save the output into Input_file itself(it will create a output directory named temp_file and then rename/move temp_file to your actual Input_file).

Upvotes: 1

choroba
choroba

Reputation: 241758

GNU-sed has an extension that can operate on every n-th line:

sed '4~4s/.$//'

m~n means on the m-th line repeated every n lines, run the following command.

Upvotes: 6

Related Questions