Pergunta

I would like to read a file line by line, edit the line and put it into a new file:

while read my_line
do
    # doesn't handle the last OR
    printf "'%s'\$label OR " $my_line >> delivered 
done < "labels.txt"

Unfortunately, by following this approach, I add a OR also after the last element of my file.

I thought that in some way I could handle this case by identifying the last line: from the man page, when $? for read is different from 0, then we have the end-of-file; but in this case I can't use it inside the loop to create a different printf instruction.

Any suggestion?

Thank you

Foi útil?

Solução

Another funny solution, using :

$ cat file.txt
aaa
bbb
ccc
$ perl -pe 's/.*/\047$&\047/; !eof && s/\n/\$label OR /g' file.txt
'aaa'$label OR 'bbb'$label OR 'ccc'

This have the advantage to have a very clear syntax, isn't it ?

  • -pe stands for print by default (like sed) & assuming while (<>) {} equivalent
  • \047 stands for octal representation of single quote '
  • !eof stands for if the EOF is not reached
  • s/// is the basic skeleton for a sed like substitution

Outras dicas

You can try this:

while read my_line
do
  printf "'%s'"
  read -t 0 && printf " OR "
done < "labels.txt" > delivered

The second read (specifying a timeout of 0 seconds with -t) succeeds only if there is input available, but does not consume any input. After you have printed the last line, it will not succeed, and so you won't print the trailing "OR".

The classic workaround for this is to just append a line with 0=1. making it 'FOO' OR 'BAR' OR 0=1:

{
while read my_line
do
    # doesn't handle the last OR
    printf "'%s'\$label OR " $my_line
done 
echo 0=1
} < "labels.txt" > delivered

This has the additional benefit of turning an empty input file into the valid expression 0=1 rather than the empty string.

A simple solution with head and tail :

$ cat test.txt
aa
bb
cc
dd
$ head -n -1 test.txt|sed "s/$/ OR/"; tail -n 1 test.txt
aa OR
bb OR
cc OR
dd

head reads the file except the last line, as meant by the -1 for number of lines. Then sed adds the keyword at the end of each line, which is matched by $ in the search expression. Then tail adds the last line unmodified.

As there are two commands, to redirect the output to a file, you can run it in a subshell :

$ (head -n -1 test.txt|sed "s/$/ OR/"; tail -n 1 test.txt) > output
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top