So parse a text file and print out line 1 and line 14, and then do nothing with lines 15-46, and then print out line 47 and line 60, etc until the end of the file. So basically every 46 lines, print out the 1st and 14th line, repeatedly for every 46 lines until EOF
3 Answers
Since you have awk
in your tags, I will provide a solution with awk
:
awk '(NR%46==1||NR%46==14){print}' file
-
1Clear and concise - obviously
awk
is the right tool for this job :) Jan 16, 2018 at 2:11 -
3
awk 'NR%46==1||NR%46==14' file
suffices, since awk triggers a{print $0}
when a true condition occurs.– fedorquiJan 16, 2018 at 7:23
No job for POSIX sed
:
sed 'H;1h;$!d;x;y/\n#/#\n/;s/\(#[^#]*\)\{12\}#\([^#]*\)\([^#]*#\)\{33\}/#\2##/g;s/\(.*\)##.*/\1/;s/##/#/g;y/\n#/#\n/'
Although I consider it to be nonsense using plain POSIX sed
for such a task when other tools are better suited, I'll add an explanation, because there are useful elements here you may need in actual tasks:
H;1h;$!d;x
is a pattern to collect the whole file in the pattern space, which is often useful (with GNUsed
, you can replace it by using the-z
option). You can figure out how it works.y/\n#/#\n/
exchanges the newlines with another char (in this case#
). Do this as a workaround before and after your processing if you need expressions like "every char except newline". Again, you don't need it with GNUsed
, as[^\n]
is allowed there.- That weird pattern in the
s
command matches 12+1+33=46#
(formerly newlines) and 45[^#]*
, which are the line contents. The every first line is untouched, 12 are removed, 1 preserved as\2
and 33 removed. This is globally done. The##
stuff is done to remove trailing lines.
-
2An explanation of this magic incantation would be much appreciated. Jan 15, 2018 at 21:21
-
1Honestly? Despite that this is clearly the wrong tool? Explaining how to hammer a nail with a screwdriver? Jan 15, 2018 at 21:38
-
@shadowtalker Okay, I did. There are parts to learn for real-world cases. Jan 16, 2018 at 10:12
-
With POSIX
sed
, you can always dosed -n 'p;n;n;n;n;n;...;n;p;n;n;n...;n'
with enoughn
s. POSIX seds are not required to be able to store more than 10xLINE_MAX bytes in their hold or pattern space so storing the whole input there is not a good idea. Jan 16, 2018 at 11:02 -