0

im writing some bash exercises, this in particular wants to check all the files named file-a(sonenumber) and move it to directory named dirA But there's some problem with for loop i can do that without for loop just simply writing

mv $(ls -la | awk '$9 - /-a[0-9]+/ {print $9}') dirA

but i wanna do it with a for and i cant do that there's the script

FILES=(ls -la | awk '$9 - /-a[0-9]+/ {print $9}')

for arg in "$FILES"
do
       mv $arg dirA
done
Barmar
  • 741,623
  • 53
  • 500
  • 612
VuciuS
  • 11
  • 1

3 Answers3

3

No need a for loop, just a shell glob:

mv -- *-a[0-9]* dirA

If you insist for a loop:

files=( *-a[0-9]* )

for f in "${files[@]}"; do
    mv "$f" dirA/
done

or

for f in *-a[0-9]*; do
    mv "$f" dirA/
done

But please, avoid parsing ls output.

ls is a tool for interactively looking at directory metadata. Any attempts at parsing ls output with code are broken. Globs are much more simple AND correct: for file in *.txt. Read http://mywiki.wooledge.org/ParsingLs


Don't use UPPER case variables

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
1

You're not setting FILES to the output of the command. For that, you need to use $(command). To make it an array, wrap another set of () around that.

Then to loop over the array contents, use "${FILES[@]}.

I'm not sure why you're using ls -la when you could just use ls -a. Then each filename will be a single line, you don't have to extract $9.

FILES=($(ls -a | awk '/-a[0-9]+/'))

for arg in "${FILES[@]}"
do
       mv "$arg" dirA
done

However, it's best not to parse the output of ls.

Barmar
  • 741,623
  • 53
  • 500
  • 612
-6

I modified your code to work in the for loop.

FILES=$(ls -la | awk  '/-a[0-9]+/ {print $9}') 
for arg in $FILES 
do 
  mv $arg dirA
done
LinFelix
  • 1,026
  • 1
  • 13
  • 23
Eric
  • 21
  • 1
  • 6