I want to write a bash script than prints only odd lines of file, including the first line without used sed
or awk
, also without &&, || and ;
Asked
Active
Viewed 191 times
-4

Imane
- 7
-
2The requirements seem awfully arbitrary. What is the point? Is this a homework? The question (like any question) should show reasonable research effort. What is your attempt so far? Where are you stuck? – Kamil Maciorowski Mar 15 '23 at 08:02
-
1Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Mar 15 '23 at 08:44
-
Voted to close as too broad - it's not clear what was attempted here, and where the problem that the asker has lie. As such, a good answer would have to explain far too much – Marcus Müller Mar 15 '23 at 09:15
-
When asking questions about text processing, please be sure to always include example input along with the desired output. Also, please show what you tried and where you faced difficulties, so that contributors trying to help don't propose solutions you already know won't work. – AdminBee Mar 28 '23 at 15:47
2 Answers
3
With perl
:
$ seq 10 | perl -ne 'print if $.%2'
1
3
5
7
9
If the input doesn't contain TAB characters, you can also do:
$ seq 10 | paste - - | cut -f1
1
3
5
7
9
With GNU grep
:
$ seq 10 | grep -n '^' | LC_ALL=C grep -Po '^\d*[13579]:\K.*'
1
3
5
7
9
In any case, you shouldn't use a shell loop to process text. If that's what your teacher expects with those weird requirements, get another teacher as they'd be teaching you bad practice. A shell's role is before all to run other commands. And as a shell scripter, you want to pick the best command for the job (here perl
, sed
or awk
) or a set of commands that collaborate together as intended by the Unix authors when they invented those pipelines some 50 years ago.

Stéphane Chazelas
- 544,893
-
This
perl
solution is quite elegant, but it does not satisfy the requirements. From the question: "I want to write a bash script". Theperl
command is standalone, it's not a bash script. Your other solutions use|
, so they really require a shell like bash, this makes them little closer to "bash scripts". One can wrapperl
in a bash script though. It would make the answer better (the requirement would be met) and worse at the same time (objectively such wrapping is not the Right Thing). – Kamil Maciorowski Mar 15 '23 at 10:01 -
The
#bash@irc.libera.chat
(previously onfreenode
) team that is owning shellcheck, bash-hackers, bashFAQ, woodledge and so on, says thatseq(1) is nonstandard, inefficient and useless
Dixitgreybot
– Gilles Quénot Mar 15 '23 at 10:03 -
1@KamilMaciorowski, that's shell code that invokes
perl
. Also works in the bash shell. A shell is a tool to run commands. – Stéphane Chazelas Mar 15 '23 at 10:06 -
@GillesQuénot,
seq
here is not part of the answer, it's a tool used to provide sample data to demonstrate the answer. – Stéphane Chazelas Mar 15 '23 at 10:07 -
So… every command is a bash script. Right? A custom binary executable that solves the OP's problem out of the box is a bash script, because one can invoke it from bash. Right? – Kamil Maciorowski Mar 15 '23 at 10:08
-
@KamilMaciorowski, yes,
mytool arg
is code in the shell syntax. That executes/path/to/mytool
withmytool
, andarg
as arguments in a child process and waits for its termination. A roughly equivalent perl script would besystem("mytool", "arg");
– Stéphane Chazelas Mar 15 '23 at 10:11 -
@GillesQuénot, note that the
printf '%s\n' {1..n}
zshism (since copied by many other shells) you used in your answer is less efficient thanseq n
for large values ofn
(where efficiency matters), as it implies storing the whole list of numbers (as strings converted from numbers likely through some sprintf() call internally) in memory several times. Comparetime bash -c 'seq 10000000' > /dev/null
withtime bash -c 'printf "%s\n" {1..10000000}' > /dev/null
for instance. – Stéphane Chazelas Mar 15 '23 at 10:17 -
-
OK, I get your point. Still, when one explicitly requests a bash script, a solution that uses bash only to invoke a tool that uses another language to do all the job single-handedly is not necessarily what he or she means. I suspect this is the reason
awk
andsed
are explicitly forbidden. The question is probably a homework-like task and the point probably is to use bash for something more than invoking a single executable. IMO if calling theperl
solution "bash script" meets the requirements, so would a solution usinggawk
.gawk
is not forbidden,awk
is; why not usegawk
? – Kamil Maciorowski Mar 15 '23 at 10:43 -
2@KamilMaciorowski, but IMO, giving a solution using a shell loop to process text, even one that only uses builtin commands of one particular shell implementation would be a disservice to the OP. If that's what their teacher want, they should get another teacher. – Stéphane Chazelas Mar 15 '23 at 11:06
-
0
You could do:
while IFS= read -r line
do
printf "%s\n" "$line"
IFS= read -r _
done <"file"
Trying with seq
:
while IFS= read -r line
do
printf "%s\n" "$line"
IFS= read -r _
done < <(seq 10)
1
3
5
7
9

drewk
- 241