Есть ли какой-либо флаг команды du (использование диска), который суммирует размер для каждого подкаталога

Лично я бы избегал жесткого кодирования имен файлов. Это редко бывает хорошей идеей, и обычно лучше иметь возможность передавать целевые файлы в качестве аргументов. Кроме того, вы изменяете файл на месте, а затем удаляете оригинал. Это неэффективно, просто измените файл на лету и распечатайте седьмой столбец, не записывая его на диск. Например:

#!/usr/bin/env bash

## Iterate over the file names given
for file in "$@"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done

Затем вы можете запустить скрипт следующим образом:

foo.sh /tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt 

Если вы хотите, чтобы имена были жестко закодированы, просто используйте массив, как предлагает @choroba:

#!/usr/bin/env bash

files=(/tmp/1wall_long.txt /tmp/1wall_test1.txt /tmp/1wall_test2.txt /tmp/1wall_test3.txt /tmp/20mt_OpenSpace_test1.txt /tmp/20mt_OpenSpace_test2.txt /tmp/20mt_OpenSpace_test3.txt /tmp/3mt_long.txt /tmp/3mt_OpenSpace_test1.txt /tmp/3mt_OpenSpace_test2.txt /tmp/3mt_OpenSpace_test3.txt /tmp/3rooms_test1.txt /tmp/3rooms_test2.txt /tmp/3rooms_test3.txt )


## Iterate over the file names given
for file in "${files[@]}"; do
    ## Get the output file's name. The ${file%.*} is
    ## the file's anme without its extension.
    outfile="${file%.*}"_S.txt
    ## If the file exists
    if [ -e "$file" ]; then
    ## remove the spaces and print the 7th column
    sed 's/- /-/g' "$file" | awk '{print $7}' > "$outfile" &&
        ## Delete the original but only if the step
        ## above was successful (that's what the && does)/
        rm "$file" 
    else
    ## If the file doesn't exist, print an error message
    echo "The file $file does not exist!"
    fi
done
5
21.11.2018, 23:29
2 ответа

Некоторые реализации duподдерживают -d¹ для ограничения глубины отображения использования диска (не учитывают использование диска ), поэтому du -hd 1.должно работать для текущего каталога.

Переносимо всегда можно сделать:

find. ! -name. -prune -type d -exec du -s {} +

(добавьте -h, если ваша реализация duподдерживает это)

Однако обратите внимание, что если в текущем каталоге много каталогов, findможет привести к нескольким вызовам du, что может означать, что некоторые жесткие ссылки учитываются несколько раз. Некоторые реализации duтакже не предотвращают многократный подсчет жестких ссылок, если они встречаются при обходе различных аргументов.


¹, в старых версиях GNU duвам может понадобиться --max-depth. Эквивалент короткой опции -dбыл добавлен только в coreutils 8.8 для совместимости с FreeBSD

10
27.01.2020, 20:32

Может быть, я упускаю из виду то, о чем вы просите, но я думаю

du -sh *

делает именно то, что вы хотите. Здесь важно *. С -sвы получаете сводку для каждого каталога в командной строке , так что без явного каталога (неявного.)вы просто получите сводку для всего, а не для каждого из каталоги под верхним -уровнем по отдельности.

1
27.01.2020, 20:32

Теги

Похожие вопросы