Вот версия awk + для цикла:
for filename in *; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
И вот это действие
$ ls
$ echo "TEST" | tee {foo,bar}_{yolo,swag}_{whatever,else}.txt
TEST
$ ls
bar_swag_else.txt bar_yolo_else.txt foo_swag_else.txt foo_yolo_else.txt
bar_swag_whatever.txt bar_yolo_whatever.txt foo_swag_whatever.txt foo_yolo_whatever.txt
$ for filename in *; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
$ ls
bar swag else.txt bar yolo else.txt foo swag else.txt foo yolo else.txt
bar swag whatever.txt bar yolo whatever.txt foo swag whatever.txt foo yolo whatever.txt
Чтобы учесть новые строки и возможные переименование каталогов, вот типичная конструкция IFS + find + read + while. После того, как вы предложили, запустите сначала версию с find . -type d -print0, потому что если вы сначала начнете переименование файлов, а подкаталог содержит символ подчеркивания, имя файла не будет изменено. Короче говоря, сначала позаботьтесь о каталогах и подкаталогах, затем позаботьтесь о файлах
$ ls
file_bar_swag.txt file_bar_yolo.txt file_test_swag.txt file_test_yolo.txt foo_bar_swag.txt foo_bar_yolo.txt foo_test_swag.txt foo_test_yolo.txt tester_dir
$ ls tester_dir/
ber_sweg_elze.txt ber_sweg_whut.txt ber_yelo_elze.txt ber_yelo_whut.txt fee_sweg_elze.txt fee_sweg_whut.txt fee_yelo_elze.txt fee_yelo_whut.txt
$ find . -type d -print0 | while IFS="" read -r -d "" filename ; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
mv: ‘.’ and ‘./.’ are the same file
$ ls
file_bar_swag.txt file_bar_yolo.txt file_test_swag.txt file_test_yolo.txt foo_bar_swag.txt foo_bar_yolo.txt foo_test_swag.txt foo_test_yolo.txt tester dir
$ find . -type f -print0 | while IFS="" read -r -d "" filename ; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
mv: ‘./.yolo’ and ‘./.yolo’ are the same file
$ ls
file bar swag.txt file bar yolo.txt file test swag.txt file test yolo.txt foo bar swag.txt foo bar yolo.txt foo test swag.txt foo test yolo.txt tester dir
Как вы можете видеть, есть небольшая проблема - поскольку команда find также отображает текущий каталог (символизируется .), команда создаст побочный продукт - файл с ведущей точкой.
Добавление ! -path . при работе с каталогами решает проблему
$ find . ! -path . -type d -print0 | while IFS="" read -r -d "" filename ; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
$ find . -type f -print0 | while IFS="" read -r -d "" filename ; do NEWNAME=$(echo "$filename" | awk '{gsub("_"," "); print}'); mv "$filename" "$NEWNAME";done
$ ls
file bar swag.txt file bar yolo.txt file baz swag.txt file baz yolo.txt foo bar swag.txt foo bar yolo.txt foo baz swag.txt foo baz yolo.txt tester dir
$ ls "tester dir"
file bar.txt file baz.txt foo bar.txt foo baz.txt
$ ls -a
. .. file bar swag.txt file bar yolo.txt file baz swag.txt file baz yolo.txt foo bar swag.txt foo bar yolo.txt foo baz swag.txt foo baz yolo.txt tester dir
Использование grep с PCRE (-P):
diskutil info / | grep -Po 'Free Space:\s+\K[^(]+(?=\s+\()'
Free Space:\s+ соответствует части до желаемого выхода, \K отбрасывает совпадение [^(]+, совпадающее с желаемым выходом, нулевая ширина позиционного шаблона (f9) гарантирует, что за совпадением следуют пробелы и (. Аналогичная логика с использованием sed:
diskutil info / | sed -r 's/.*Free Space:\s+([^(]+)\s+\(.*/\1/'
Пример:
% grep -Po 'Free Space:\s+\K[^(]+(?=\s+\()' <<<'Volume Free Space: 31.5 GB (31519584256 Bytes) (exactly 61561688 512-Byte-Units)'
31.5 GB
% sed -r 's/.*Free Space:\s+([^(]+)\s+\(.*/\1/' <<<'Volume Free Space: 31.5 GB (31519584256 Bytes) (exactly 61561688 512-Byte-Units)'
31.5 GB
В Ubuntu 14.04 и выше просто используйте df:
$ df -h --output=size /
Size
30G
Чтобы избавиться от заголовка столбца:
$ df -h --output=size / | tail -1
30G