# zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

### Defragging files in btrfs - Oneliner

April 10, 2020 — Jesse Harris

Sometimes, small databasey files get a bit fragmented over time on a COW filesystem. This touch of shell is a goodone to clean them up every now and then.

        find -size +1024k -size 50000k -type f -exec filefrag {} \; |
        awk '{a=NF-2; if ($a>50) {sub(/:.*/,"");print$0}}'|
        xargs -I{} btrfs fi defrag "{}"

# Pulling it apart

## find

        -size +1024k -size -50000k
        # this tells find to only show files between 1mb and 50mb

        -type f
        # only find files

        -exec filefrag {} ;\
        # run filefrag on each file, which shows a count of fragments on each
        # file

## awk

        a=NF-2
        # files may have spaces in the name and filefrag lists the filename
        # first, instead lets look the second from the last field number (NF =
        Number of fields in a given line)

        if ($a>50)
        # only work on files with frags over 50

        sub(/:.*/,"")
        # from $0 (the whole line), substitue anything past : with nothing,
        # making $0 reference the filename, spaces and all

## xargs

        -I{}
        # in the following command substitue {} with the incoming stdin (ie the
        # filename

        btrfs fi defrag "{}"
        # defrag the file.

Tags: btrfs, bash, bash-tips, awk