I have a directory of .txt files. For each, i'd like to grab the 2nd and 7th line, and add those lines to another file, which I've arbitrarily named list.index. I'm not sure how to tell sed about the current filename, within the for loop, so what I have below doesn't work yet.

for i in *.txt
sed -n -e '2p' -e '7p' list.index
  • I guess something like find -name \*.txt -exec sed -n -e '2p;7p' {} \; > list.index should work as well – Hagen von Eitzen Jan 12 '14 at 21:28

In your case, you had told sed that print 2nd and 7th line of file list.index, not add those lines to it.

Try this:

for i in *.txt
    sed -n -e '2p;7p' < "$i" >> list.index

It will print 2nd and 7th line of each file .txt then add them to list.index.

  • This worked like a charm. I see now that I can use $i to name the file within a loop. And I can do >> list.index to define the file to print to. Thank you. – Dylan Kinnett Jan 11 '14 at 17:20

Note that you can tell sed to stop reading after it's read the 7th line, there's no point keeping reading after that:

#! /bin/sh -
for i in *.txt; do
  sed -e 2b -e 7q -e d < "$i"
done > list.index

(or sed '7q;2!d' < "$i" shorter but slightly less legible)

  • While this 7q;2!d is a genius pieve of code, I wonder why nobody did the obvious and leave away the for loop by using option -s: sed -sn '2p;7p' *.txt > list.index – Philippos Mar 27 '17 at 16:00
  • @Philippos, note that -s is a non-standard GNU extension. Contrary to the approaches using q, that would also read the files fully (past the 7th line). See also awk with nextfile for a slightly more portable approach. (you'd also need sed -sn ... ./*.txt or sed -sn -- '...' *.txt with GNU sed unless POSIXLY_CORRECT is in the environment). – Stéphane Chazelas Mar 27 '17 at 16:06
  • Thank you, good to know! The man page usually tells about which options and commands are gnu extensions, but it doesn't say so for -s. Also, it still works with option --posix. Strange. – Philippos Mar 27 '17 at 16:18
  • @Philippos, POSIX doesn't forbid implementations from supporting a -s option. POSIX doesn't mandate implementations to return an error when applications (scripts/users) pass an option that is not specified, so there's no reason --posix should affect that behaviour. A script that uses -s would not be compliant/portable as POSIX doesn't specify that option. – Stéphane Chazelas Mar 27 '17 at 16:23
  • 1
    @Philippos, you're right. I should have checked the manual, I assumed --posix would be the same as passing POSIXLY_CORRECT in the environment. Note that POSIX doesn't specify a --posix option, so that option itself is a GNU extension. – Stéphane Chazelas Mar 28 '17 at 7:29

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.