1

I have a large number of files in a directory in a linux server with this name pattern:

1_file.txt
2_file.txt
3_file.txt
...
1455728_file.txt

Is there a way to move the first 100000 files (1_file.txt to 100000_file.txt) into directory 1_100000, the second 100000 files (100001_file.txt to 200000_file.txt) into directory 100001_200000, and so on ... ?

  • 1
    Yes. You can do this using a shell script that uses a for loop to mv each file into the correct location. Alternatively, it might be easier to pipe the output from ls into split -l 100000 in order to generate the directories you want. Maybe someone else will come along and write a one-liner for you. – sjy Sep 15 at 0:02
  • You are more likely to get help if you show your attempts or at least sketch one, as sjy has kindly done above. – Quasímodo Sep 15 at 0:37
2

Untested

I would do something like:

#!/bin/bash
bottom=0
while [[ $bottom -lt 150000 ]] ; do
    myfirst=$((bottom + 1))
    mylast=$((bottom + 100000))
    bottom=$((bottom + 100000))

    dir="${myfirst}_$mylast"
    [[ -d "$dir" ]] || mkdir "$dir"
    seq $myfirst $mylast | \
        while read p ; do
            q="${p}_file.txt"
            [[ -f "$q" ]] && echo "$q"
        done | \
            xargs --no-run-if-empty  echo mv -t "$dir"

done

Remove the echo from echo mv when you want to do it for real.

| improve this answer | |
  • That is exactly what I needed. Thanks! – Bahram Sep 15 at 14:49
0

script.sh

#!/bin/bash

step=100000
file_dir=$1

# Counting of files in the directory
shopt -s nullglob
file_list=("${file_dir}"/*)
file_num=${#file_list[@]}

# Every file's common part
suffix='_file.txt'

for((from = 1, to = step; from <= file_num; from += step, to += step)); do
    new_dir="${from}_${to}"
    mkdir "${file_dir}/${new_dir}"

    if ((to > file_num)); then
        to="$file_num"
    fi
    
    # Generating filenames by `seq` command and passing them to `xargs`
    seq -f "${file_dir}/%.f${suffix}" "$from" "$to" | xargs mv -t "${file_dir}/${new_dir}"
done

Usage: ./script.sh files

Testing

I have generated files by this command:

printf '%s\0' files/{1..1455728}_file.txt | xargs -0 touch

then do:

$ time ./script.sh files

# Time is:
real    10m43,618s
user    0m9,953s
sys 0m19,671s

Quite slow.

Result

$ ls -1v files
1_100000
100001_200000
200001_300000
300001_400000
400001_500000
500001_600000
600001_700000
700001_800000
800001_900000
900001_1000000
1000001_1100000
1100001_1200000
1200001_1300000
1300001_1400000
1400001_1500000
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.