3

I just started using shell programming. I want to automatically change directories and then rename some files in there. Here's my problem: The name of the directories are numbered but directories < 10 are zero-padded (01 02...09). How can I define an array using some sort of sequencing without typing each directory name manually? This is what I've tried so far:

array = (printf "%.2d "  {1..8}  {11..27}  {29..32} {34..50})    ## should say 01 02 03 ..08 11..27 29..32 34..50

for i in "${array[@]}"
do
  echo "dir_a/dir_b/sub$i/dir_c/"
done

However, it doesn't work and the result looks like: "subprintf", "sub%.2s", "sub1" etc. Can you help me there?

In a next step I want to filter certain numbers in the array, e.g. 03, 09, 10, 28, 33 as these directories don't exist. Is there some easy solution to create such an array without concatenating 5 separate arrays?

Many thanks in advance, Kati

1
  • In general, you cannot put whitespace around the equal sign in a parameter assignment: array=(... Commented Nov 26, 2013 at 17:48

4 Answers 4

2

Is there a need to use arrays? Otherwise, for 4, you can do

for i in {01..08} {11..27} {29..32} {34..50}; do
    echo "dir_a/dir_b/sub${i}/dir_c/"
done

For an older version of you have to add the 0 yourself:

for i in 0{1..8} {11..27} {29..32} {34..50}; do
    echo "dir_a/dir_b/sub${i}/dir_c/"
done

Of course, if you want to have an array, you can do

array=({01..08} {11..27} {29..32} {34..50})

or

array=(0{1..8} {11..27} {29..32} {34..50})
Sign up to request clarification or add additional context in comments.

Comments

0

You could do this:

declare -a dirs=('01' '02' '03' '04' '05' '06' '07' '08')
echo ${dirs[@]}
01 02 03 04 05 06 07 08

# Make up next sequence
declare -a b=`seq 11 18`
echo ${b[@]}
11 12 13 14 15 16 17 18

# Add sequences together
dirs=("${dirs[@]}" ${b})
echo ${dirs[@]}
01 02 03 04 05 06 07 08 11 12 13 14 15 16 17 18

Comments

0
find [0-9][0-9] -type d | while read dirname
do
    if [ $(echo "${dirname}" | sed -n '/01/p') ]
    then
    cd "${dirname}"
    mv foo bar
    cd ..
    fi
done

Then you can just write another elif and sed check for every directory which contains files you want to rename. I know it's not what you asked for, but it is infinitely simpler. If you're allowed to, I'd also strongly recommend renaming that directory tree, as well.

Comments

0
#/bin/bash

raw=({01..08} {11..27} {29..32} {34..50})
filter=(03 09 10 28 33)

is_in() {
    for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
    return 1
 }

for i in ${raw[@]}; do
    is_in $i ${filter[@]} || echo "dir_a/dir_b/sub$i/dir_c"
done

It'll take the numbers in the raw array and exclude every occurance of the ones in the filter array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.