I'm trying to run a shell script that counts the number of rows in each file, and if the number < 2 I need to move it to a different directory.



foreach i in (ls *.DAT)
  a=`wc -l $i`
  if $a=<2 then
    mv $i aux1/pelvar/var/pel/projs/ar/shells/IGUD_OUT/backup      

But my shell gets an error:

igud_to_backup.sh: line 8: syntax error near unexpected token `('

igud_to_backup.sh: line 8: `foreach i in (ls *.DAT)'

What is wrong with the shell script?


2 Answers 2


There are many problems:

  • foreach is not a bash keyword: use for
  • if you want to execute a command use $( ... ) and not just the parenthesis
  • the command execution in the parenthesis is not needed you can just use shell expansion for i in *.DAT; do (in general see Why *not* parse `ls`?)
  • to test if a value is less or equal (see man test): if [ $a -le 2 ] ; then
  • a for is ended by done and not end
  • an if is ended by fi and not endif
  • if you give the file name as an argument to wc it will print the number of lines and the file name. Use < to make wc read from standard input

To sum up:

for i in *DAT; do
  a=$( wc -l < "$i" )
  if [ "$a" -le 2 ] ; then
    mv "$i" aux1/pelvar/var/pel/projs/ar/shells/IGUD_OUT/backup
  • Hey, thanks a lot, now it is much better. but still getting error: unknown operator
    – Elislu
    Jun 28, 2016 at 10:59
  • @don_crissti Oops sorry
    – Matteo
    Jun 28, 2016 at 11:06
  • @Elislu What do you mean?
    – Matteo
    Jun 29, 2016 at 10:13
  • Hey, The Shell: #!/bin/sh for i in $(ls *.DAT); do if [ "$a" -ge 2 ] ; then mv ${i} /aux1/pelvar/var/pel/projs/ar/shells/IGUD_OUT/backup fi done He should count how many rows there are in each file and then with two or more rows, he should move it to another directory. But unfortunately it does not work :(
    – Elislu
    Jun 29, 2016 at 10:19
  • The code you posted in the last comment is not what I suggested. But more importantly you are missing the line assigning the number of rows to a ` a=$( wc -l < "$i" )`
    – Matteo
    Jun 29, 2016 at 10:20

As Matteo mentioned you are trying to use perl syntax. Should be;

for i in $(ls *.DAT); do
  if [ $(wc -l ${i}) -le 2 ]; then
    mv ${i} /path/to/
  • Looks more like csh syntax to me, but anyway, it isn't bash.
    – Kusalananda
    Jun 28, 2016 at 11:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .