Как получить определенную часть результата команды?

Вот версия 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
1
задан 12 March 2016 в 17:06

2 ответа

Использование 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
2
ответ дан 23 May 2018 в 12:54

В Ubuntu 14.04 и выше просто используйте df:

$ df -h --output=size /
 Size
  30G

Чтобы избавиться от заголовка столбца:

$ df -h --output=size / | tail -1 
  30G
2
ответ дан 23 May 2018 в 12:54

Другие вопросы по тегам:

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