How to select certain lines (n, n+4, n+8, n+12…) from the file?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
Input:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
Expected output:
1
2
3
4
So, I need to have only 1st, 5th, 9th, 13th value of the file in the output file. How to do this?
text-processing
add a comment |
Input:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
Expected output:
1
2
3
4
So, I need to have only 1st, 5th, 9th, 13th value of the file in the output file. How to do this?
text-processing
2
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can dosed -n '1~4p'
– Sundeep
May 9 at 7:55
1
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56
add a comment |
Input:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
Expected output:
1
2
3
4
So, I need to have only 1st, 5th, 9th, 13th value of the file in the output file. How to do this?
text-processing
Input:
1
hgh
h2b
h4h
2
ok
koko
lkopk
3
uh
ju
nfjvn
4
Expected output:
1
2
3
4
So, I need to have only 1st, 5th, 9th, 13th value of the file in the output file. How to do this?
text-processing
text-processing
edited May 9 at 7:34
Stephen Kitt
188k26437517
188k26437517
asked May 9 at 7:04
VeluVelu
13616
13616
2
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can dosed -n '1~4p'
– Sundeep
May 9 at 7:55
1
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56
add a comment |
2
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can dosed -n '1~4p'
– Sundeep
May 9 at 7:55
1
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56
2
2
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can do
sed -n '1~4p'– Sundeep
May 9 at 7:55
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can do
sed -n '1~4p'– Sundeep
May 9 at 7:55
1
1
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56
add a comment |
8 Answers
8
active
oldest
votes
Using AWK:
awk '!((NR - 1) % 4)' input > output
Figuring out how this works is left as an exercise for the reader.
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
NR % 4 == 1would be more legible IMO.
– Stéphane Chazelas
May 9 at 8:42
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
add a comment |
Using split (GNU coreutils):
split -nr/1/4 input > output
-ngenerateCHUNKSoutput files
and CHUNKS as
r/K/Nuse round robin distribution and only output Kth of N to stdout without splitting lines/records
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
add a comment |
With GNU sed:
sed '1~4!d' < input > output
With standard sed:
sed -n 'p;n;n;n' < input > output
With 1 and 4 in $n and $i variables:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
add a comment |
Adding the obligatory perl solution:
perl -ne 'print if $. % 4 == 1' input > output
add a comment |
Python version, just for fun:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
enumerate(f)should be able to do the job while consuming less memory
– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to usereadlines(hence slurping the whole file into memory), you can usef.readlines()[::4]to get every fourth line. So you can useprint(''.join(f.readlines()[::4])).
– kundor
May 14 at 16:40
add a comment |
POSIX sed: this method uses the posixly sed and so can be run everywhere, or atleast those seds that respect posix.
$ sed -ne '
/n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/n/&/4
tdone
bloop
:done
s/.//;P
' input.file
Another is a programmatic sed code generation for scalability purposes:
$ code=$(yes n | head -n 4 | paste -sd; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: we fill-up array A till it is 4 in size. Then we print its first element and also clear out the array.
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
add a comment |
Call with scriptname filename skip (4 in your case)
It works by pulling iter lines from the top of the file and then only outputting the last. It then increments iter by skips and repeats as long as the value of iter hasn't exceeded the lines in file.
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
add a comment |
Pure Bash:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%sn" "${lines[$i]}"
done
mapfile is a builtin added in Bash 4 which reads standard input into an array, here named lines, with one line per entry. The -t option strips the final newlines.
If you want to print every fourth line starting from line 4, then you can do that in one command using mapfile's callback option -C, which runs the provided code every so many lines, with the interval given by -c. The current array index and the next line to be assigned are given to the code as arguments.
mapfile -t -c4 -C 'printf "%.0s%sn"' < input
This uses the printf builtin; the format code %.0s suppresses the first argument (the index), so only the line is printed.
You could use the same command to print every fourth line starting from line 1, 2, or 3, but you'd have to prepend 3, 2, or 1 lines to input before feeding it to mapfile, which I think is more trouble than it's worth.
This also works:
mapfile -t lines < input
printf "%s%.0s%.0s%.0sn" "${lines[@]}"
Here, printf consumes four entries of the array lines at a time, only printing the first and skipping the other three with %.0s. I don't like this since you have to manually fiddle with the format string for different intervals or starting points.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f517924%2fhow-to-select-certain-lines-n-n4-n8-n12-from-the-file%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
Using AWK:
awk '!((NR - 1) % 4)' input > output
Figuring out how this works is left as an exercise for the reader.
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
NR % 4 == 1would be more legible IMO.
– Stéphane Chazelas
May 9 at 8:42
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
add a comment |
Using AWK:
awk '!((NR - 1) % 4)' input > output
Figuring out how this works is left as an exercise for the reader.
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
NR % 4 == 1would be more legible IMO.
– Stéphane Chazelas
May 9 at 8:42
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
add a comment |
Using AWK:
awk '!((NR - 1) % 4)' input > output
Figuring out how this works is left as an exercise for the reader.
Using AWK:
awk '!((NR - 1) % 4)' input > output
Figuring out how this works is left as an exercise for the reader.
answered May 9 at 7:08
Stephen KittStephen Kitt
188k26437517
188k26437517
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
NR % 4 == 1would be more legible IMO.
– Stéphane Chazelas
May 9 at 8:42
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
add a comment |
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
NR % 4 == 1would be more legible IMO.
– Stéphane Chazelas
May 9 at 8:42
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
thanks for this short awk course!
– darxmurf
May 9 at 7:31
thanks for this short awk course!
– darxmurf
May 9 at 7:31
20
20
NR % 4 == 1 would be more legible IMO.– Stéphane Chazelas
May 9 at 8:42
NR % 4 == 1 would be more legible IMO.– Stéphane Chazelas
May 9 at 8:42
12
12
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
Agreed @Stéphane; this is probably questionable on my part, but for potentially homework questions I try to obfuscate my answers a little...
– Stephen Kitt
May 9 at 9:47
add a comment |
Using split (GNU coreutils):
split -nr/1/4 input > output
-ngenerateCHUNKSoutput files
and CHUNKS as
r/K/Nuse round robin distribution and only output Kth of N to stdout without splitting lines/records
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
add a comment |
Using split (GNU coreutils):
split -nr/1/4 input > output
-ngenerateCHUNKSoutput files
and CHUNKS as
r/K/Nuse round robin distribution and only output Kth of N to stdout without splitting lines/records
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
add a comment |
Using split (GNU coreutils):
split -nr/1/4 input > output
-ngenerateCHUNKSoutput files
and CHUNKS as
r/K/Nuse round robin distribution and only output Kth of N to stdout without splitting lines/records
Using split (GNU coreutils):
split -nr/1/4 input > output
-ngenerateCHUNKSoutput files
and CHUNKS as
r/K/Nuse round robin distribution and only output Kth of N to stdout without splitting lines/records
answered May 9 at 10:52
FreddyFreddy
3,8231417
3,8231417
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
add a comment |
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
1
1
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
Mind blown. Answers like this are why I love this SE. Thanks!
– user1717828
May 9 at 12:04
add a comment |
With GNU sed:
sed '1~4!d' < input > output
With standard sed:
sed -n 'p;n;n;n' < input > output
With 1 and 4 in $n and $i variables:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
add a comment |
With GNU sed:
sed '1~4!d' < input > output
With standard sed:
sed -n 'p;n;n;n' < input > output
With 1 and 4 in $n and $i variables:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
add a comment |
With GNU sed:
sed '1~4!d' < input > output
With standard sed:
sed -n 'p;n;n;n' < input > output
With 1 and 4 in $n and $i variables:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
With GNU sed:
sed '1~4!d' < input > output
With standard sed:
sed -n 'p;n;n;n' < input > output
With 1 and 4 in $n and $i variables:
sed "$n~$i!d" # GNU only
awk -v n="$n" -v i="$i" 'NR >= n && (NR % i) == (n % i)'
edited May 9 at 10:31
answered May 9 at 8:09
Stéphane ChazelasStéphane Chazelas
320k57607978
320k57607978
add a comment |
add a comment |
Adding the obligatory perl solution:
perl -ne 'print if $. % 4 == 1' input > output
add a comment |
Adding the obligatory perl solution:
perl -ne 'print if $. % 4 == 1' input > output
add a comment |
Adding the obligatory perl solution:
perl -ne 'print if $. % 4 == 1' input > output
Adding the obligatory perl solution:
perl -ne 'print if $. % 4 == 1' input > output
answered May 9 at 10:51
wurtelwurtel
11.4k11628
11.4k11628
add a comment |
add a comment |
Python version, just for fun:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
enumerate(f)should be able to do the job while consuming less memory
– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to usereadlines(hence slurping the whole file into memory), you can usef.readlines()[::4]to get every fourth line. So you can useprint(''.join(f.readlines()[::4])).
– kundor
May 14 at 16:40
add a comment |
Python version, just for fun:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
enumerate(f)should be able to do the job while consuming less memory
– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to usereadlines(hence slurping the whole file into memory), you can usef.readlines()[::4]to get every fourth line. So you can useprint(''.join(f.readlines()[::4])).
– kundor
May 14 at 16:40
add a comment |
Python version, just for fun:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
Python version, just for fun:
with open('input.txt') as f:
for i, line in enumerate(f.readlines()):
if i%4 == 0:
print(line.strip())
answered May 9 at 12:45
user1717828user1717828
1,75531427
1,75531427
enumerate(f)should be able to do the job while consuming less memory
– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to usereadlines(hence slurping the whole file into memory), you can usef.readlines()[::4]to get every fourth line. So you can useprint(''.join(f.readlines()[::4])).
– kundor
May 14 at 16:40
add a comment |
enumerate(f)should be able to do the job while consuming less memory
– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to usereadlines(hence slurping the whole file into memory), you can usef.readlines()[::4]to get every fourth line. So you can useprint(''.join(f.readlines()[::4])).
– kundor
May 14 at 16:40
enumerate(f) should be able to do the job while consuming less memory– iruvar
May 10 at 20:17
enumerate(f) should be able to do the job while consuming less memory– iruvar
May 10 at 20:17
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
@iruvar That's so neat! Never realized that before; will be using in the future. Feel free to edit it into this answer; I'm not really going to maintain it with optimizations since the other Bash answers (especially this one) are definitely the way to go.
– user1717828
May 10 at 20:37
If you're going to use
readlines (hence slurping the whole file into memory), you can use f.readlines()[::4] to get every fourth line. So you can use print(''.join(f.readlines()[::4])).– kundor
May 14 at 16:40
If you're going to use
readlines (hence slurping the whole file into memory), you can use f.readlines()[::4] to get every fourth line. So you can use print(''.join(f.readlines()[::4])).– kundor
May 14 at 16:40
add a comment |
POSIX sed: this method uses the posixly sed and so can be run everywhere, or atleast those seds that respect posix.
$ sed -ne '
/n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/n/&/4
tdone
bloop
:done
s/.//;P
' input.file
Another is a programmatic sed code generation for scalability purposes:
$ code=$(yes n | head -n 4 | paste -sd; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: we fill-up array A till it is 4 in size. Then we print its first element and also clear out the array.
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
add a comment |
POSIX sed: this method uses the posixly sed and so can be run everywhere, or atleast those seds that respect posix.
$ sed -ne '
/n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/n/&/4
tdone
bloop
:done
s/.//;P
' input.file
Another is a programmatic sed code generation for scalability purposes:
$ code=$(yes n | head -n 4 | paste -sd; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: we fill-up array A till it is 4 in size. Then we print its first element and also clear out the array.
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
add a comment |
POSIX sed: this method uses the posixly sed and so can be run everywhere, or atleast those seds that respect posix.
$ sed -ne '
/n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/n/&/4
tdone
bloop
:done
s/.//;P
' input.file
Another is a programmatic sed code generation for scalability purposes:
$ code=$(yes n | head -n 4 | paste -sd; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: we fill-up array A till it is 4 in size. Then we print its first element and also clear out the array.
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
POSIX sed: this method uses the posixly sed and so can be run everywhere, or atleast those seds that respect posix.
$ sed -ne '
/n/!{
H;s/.*//;x
}
:loop
$bdone
N;s/n/&/4
tdone
bloop
:done
s/.//;P
' input.file
Another is a programmatic sed code generation for scalability purposes:
$ code=$(yes n | head -n 4 | paste -sd; | sed s/n/p/)
$ sed -ne "$code" input.file
Perl: we fill-up array A till it is 4 in size. Then we print its first element and also clear out the array.
$ perl -pe '
$A[@A] = @A ? <> : $_ while @A < 4;
$_ = (splice @A)[0];
' input.file
edited May 9 at 14:10
answered May 9 at 14:05
Rakesh SharmaRakesh Sharma
549126
549126
add a comment |
add a comment |
Call with scriptname filename skip (4 in your case)
It works by pulling iter lines from the top of the file and then only outputting the last. It then increments iter by skips and repeats as long as the value of iter hasn't exceeded the lines in file.
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
add a comment |
Call with scriptname filename skip (4 in your case)
It works by pulling iter lines from the top of the file and then only outputting the last. It then increments iter by skips and repeats as long as the value of iter hasn't exceeded the lines in file.
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
add a comment |
Call with scriptname filename skip (4 in your case)
It works by pulling iter lines from the top of the file and then only outputting the last. It then increments iter by skips and repeats as long as the value of iter hasn't exceeded the lines in file.
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
Call with scriptname filename skip (4 in your case)
It works by pulling iter lines from the top of the file and then only outputting the last. It then increments iter by skips and repeats as long as the value of iter hasn't exceeded the lines in file.
#!/bin/bash
file="$1"
lines=`wc -l < "$file"`
skips="$2" || "4"
iter=1
while [ "$iter" -le "$lines" ]; do
head "$file" -n $iter | tail -n 1
iter=$(( $iter + $skips ))
done
edited May 9 at 18:13
answered May 9 at 7:24
Ryan GrangeRyan Grange
114
114
add a comment |
add a comment |
Pure Bash:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%sn" "${lines[$i]}"
done
mapfile is a builtin added in Bash 4 which reads standard input into an array, here named lines, with one line per entry. The -t option strips the final newlines.
If you want to print every fourth line starting from line 4, then you can do that in one command using mapfile's callback option -C, which runs the provided code every so many lines, with the interval given by -c. The current array index and the next line to be assigned are given to the code as arguments.
mapfile -t -c4 -C 'printf "%.0s%sn"' < input
This uses the printf builtin; the format code %.0s suppresses the first argument (the index), so only the line is printed.
You could use the same command to print every fourth line starting from line 1, 2, or 3, but you'd have to prepend 3, 2, or 1 lines to input before feeding it to mapfile, which I think is more trouble than it's worth.
This also works:
mapfile -t lines < input
printf "%s%.0s%.0s%.0sn" "${lines[@]}"
Here, printf consumes four entries of the array lines at a time, only printing the first and skipping the other three with %.0s. I don't like this since you have to manually fiddle with the format string for different intervals or starting points.
add a comment |
Pure Bash:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%sn" "${lines[$i]}"
done
mapfile is a builtin added in Bash 4 which reads standard input into an array, here named lines, with one line per entry. The -t option strips the final newlines.
If you want to print every fourth line starting from line 4, then you can do that in one command using mapfile's callback option -C, which runs the provided code every so many lines, with the interval given by -c. The current array index and the next line to be assigned are given to the code as arguments.
mapfile -t -c4 -C 'printf "%.0s%sn"' < input
This uses the printf builtin; the format code %.0s suppresses the first argument (the index), so only the line is printed.
You could use the same command to print every fourth line starting from line 1, 2, or 3, but you'd have to prepend 3, 2, or 1 lines to input before feeding it to mapfile, which I think is more trouble than it's worth.
This also works:
mapfile -t lines < input
printf "%s%.0s%.0s%.0sn" "${lines[@]}"
Here, printf consumes four entries of the array lines at a time, only printing the first and skipping the other three with %.0s. I don't like this since you have to manually fiddle with the format string for different intervals or starting points.
add a comment |
Pure Bash:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%sn" "${lines[$i]}"
done
mapfile is a builtin added in Bash 4 which reads standard input into an array, here named lines, with one line per entry. The -t option strips the final newlines.
If you want to print every fourth line starting from line 4, then you can do that in one command using mapfile's callback option -C, which runs the provided code every so many lines, with the interval given by -c. The current array index and the next line to be assigned are given to the code as arguments.
mapfile -t -c4 -C 'printf "%.0s%sn"' < input
This uses the printf builtin; the format code %.0s suppresses the first argument (the index), so only the line is printed.
You could use the same command to print every fourth line starting from line 1, 2, or 3, but you'd have to prepend 3, 2, or 1 lines to input before feeding it to mapfile, which I think is more trouble than it's worth.
This also works:
mapfile -t lines < input
printf "%s%.0s%.0s%.0sn" "${lines[@]}"
Here, printf consumes four entries of the array lines at a time, only printing the first and skipping the other three with %.0s. I don't like this since you have to manually fiddle with the format string for different intervals or starting points.
Pure Bash:
mapfile -t lines < input
for (( i=0; i < ${#lines[@]}; i+=4 ))
do printf "%sn" "${lines[$i]}"
done
mapfile is a builtin added in Bash 4 which reads standard input into an array, here named lines, with one line per entry. The -t option strips the final newlines.
If you want to print every fourth line starting from line 4, then you can do that in one command using mapfile's callback option -C, which runs the provided code every so many lines, with the interval given by -c. The current array index and the next line to be assigned are given to the code as arguments.
mapfile -t -c4 -C 'printf "%.0s%sn"' < input
This uses the printf builtin; the format code %.0s suppresses the first argument (the index), so only the line is printed.
You could use the same command to print every fourth line starting from line 1, 2, or 3, but you'd have to prepend 3, 2, or 1 lines to input before feeding it to mapfile, which I think is more trouble than it's worth.
This also works:
mapfile -t lines < input
printf "%s%.0s%.0s%.0sn" "${lines[@]}"
Here, printf consumes four entries of the array lines at a time, only printing the first and skipping the other three with %.0s. I don't like this since you have to manually fiddle with the format string for different intervals or starting points.
edited May 14 at 16:13
answered May 10 at 5:56
kundorkundor
23629
23629
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f517924%2fhow-to-select-certain-lines-n-n4-n8-n12-from-the-file%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
see also: unix.stackexchange.com/questions/325985/… with GNU sed, you can do
sed -n '1~4p'– Sundeep
May 9 at 7:55
1
Related: superuser.com/questions/396536/…
– Julien Lopez
May 9 at 14:56