4

I'm trying to run a foreach loop within just 1 line of code instead of typing each indivdual command like below;

Set n=0 ; foreach txt ( *_*.txt)
foreach? sed ā€œs/_/-/gā€ $txt
foreach? @ n ++
foreach? End
echo You changed $n files

Is there any way to run all these commands all in one line instead of of the way its done above?

I'm using the tcsh shell, but am struggling to find any documentation on how foreach can work within the shell.

r0bb077
  • 165
  • 1
  • 1
  • 7
  • I don't think you can do this as a one-liner. In the past I've just stuck this into a short script and run it. Easier to maintain/modify too. – Levon May 25 '12 at 13:41

2 Answers2

3

The ability to do this on one line in csh/tcsh is somewhat limited, as pointed out on this page:

Unfortunately, the csh does not allow the use of ';' in place of new-line characters at the start of a loop, such as:

foreach fn ( * ) ; file $fn ; end <- This doesn't work

In this case, it is necessary to resort to more indirect methods.

alias check_ultras '(echo "foreach host ( tlsc0{1,2,3,4} ) " ; echo "echo :::: "\$"host :::: " ; echo "rsh "\$"host top -n -d1 7" ; echo "end" ) | csh'

  • or -

echo "while ( 1 ) \n" "xset "{,-}"led 2; sleep 1 \n" end | csh -f

So in your case, you could do something like:

alias change_files '(echo "set n=0; foreach txt ( *_*.txt )"; echo "sed 's/_/-/g' "\$"txt"; echo "@ n ++"; echo "end"; echo "echo You changed "\$"n files) | csh'
change_files

(or, to avoid creating the separate alias:)

'(echo "set n=0; foreach txt ( *_*.txt )"; echo "sed 's/_/-/g' "\$"txt"; echo "@ n ++"; echo "end"; echo "echo You changed "\$"n files) | csh'

But you could probably do this easier another way. What are you actually trying to do -- rename the files, or change the contents of those files?

0

Try this:

echo 'set n = 0 \n foreach txt (_.n) \n sed "s/_/-/g" $txt \n @ n ++ \n end \n echo "You changed $n files"' | csh -f