Disk Usage Analyzer
подсчитывает сумму пространства, используемого всеми файлами. Что-то как df
спрашивает файловая система, сколько пространства используется. Эти две суммы могут очень отличаться в зависимости от, например, сколько удаленный, но все еще открывают, файлы находятся в файловой системе.
например, если Вы делаете что-то вроде этого:
$ dd if=/dev/zero of=largefile bs=1M count=1024
$ python -c 'import time; x = open("largefile'); time.sleep(600)' &
$ rm largefile
Вы будете видеть, что 1 ГБ пространства все еще показывают df
, но не Disk Usage Analyzer
. Это вызвано тем, что, в то время как файл все еще открыт, он на самом деле не удален из диска. Когда сценарий Python закончится, файловая система освободит пространство.
Я не уверен, объясняет ли вышеупомянутое Ваш 4.4G 9G несоответствие, хотя!
Это не похоже, я не попробовал прежде, чем спросить..., вот моя попытка..., но это выглядит слишком сложным мне. Игнорируйте логику, которая обрабатывает грязные файлы корректно, это не была часть вопроса, и это не фокус текстового поиска так или иначе. Это именно так происходит, который файлы, которые я имею иногда, не запускают с "ЗАГОЛОВКА", но с небольшого количества мусора, со всей остальной частью данных, бывших прекрасных абсолютно, всегда.
#!/bin/bash
file_to_scan="${1}"
name_to_lookup="${2}"
ASSUME_FIRST_LINE_IS_HEADER="false" # Sometimes input files begin with spurious lines
FILE_HEADER_REGEX='^\[#\][[:blank:]]+OWNER_NAME[[:blank:]]+NAME[[:blank:]]+SIZE\s*$'
FIELD_HEADER_NAME=' NAME'
FIELD_HEADER_SIZE=' SIZE'
if [ "$ASSUME_FIRST_LINE_IS_HEADER" == "true" ]; then
header_line=$(head -n 1 "${file_to_scan}")
else
header_line="$(
grep \
--colour=never \
--extended-regexp \
"${FILE_HEADER_REGEX}" \
"${file_to_scan}"
)"
fi
colstartend=($(
printf "${header_line}" \
| \
awk \
-v name="${FIELD_HEADER_NAME}" \
-v size="${FIELD_HEADER_SIZE}" \
'{
print index($0, name)+1;
print index($0, size);
}'
))
sed -E "1,/${FILE_HEADER_REGEX}/d" "${file_to_scan}" \
| \
awk \
-v name_to_lookup="${name_to_lookup}" \
-v colstart="${colstartend[0]}" \
-v offset="$(( ${colstartend[1]} - ${colstartend[0]} ))" \
'{
name_field = substr($0, colstart, offset);
sub(/ *$/, "", name_field);
if (name_field == name_to_lookup) {
print substr($1, 2, length($1)-2)
}
}'
Хорошо, если бы длина столбцов не известна, я переключился бы на более мощный язык, чем удар:
#!/usr/bin/perl
use warnings;
use strict;
my $string = shift;
open my $FH, '<', '1.txt' or die $!;
my $first_line = <$FH>;
my ($before, $name) = $first_line =~ /(.* )(NAME *)/;
my $column = length $before;
$string .= ' ' x (length($name) - length $string); # adjust the length of $string
while (<$FH>) {
if ($column == index $_, $string, $column) {
/^\[([0-9]+)\]/ and print "$1\n";
}
}
Если ширина поля является постоянной - т.е. формат файла, Вы показали с шириной поля, которую Вы имеете, в их максимуме - можно использовать GNU awk (gawk(1)
) и набор FIELDWIDTHS
переменная для использования зафиксированного парсинга ширины:
gawk -v searchstr="Ideas worth zero" -- '
BEGIN { FIELDWIDTHS="6 15 27 5" } # assuming the final field width is 5
# Pre-process data
{
gsub(/[^[:digit:]]/, "", $1) # strip out non-numbers
for (i = 2; i <= NF; i++)
gsub(/[[:space:]]*$/, "", $i) # strip trailing whitespace
}
# match here
$3 == searchstr { print $1 }
' file.txt
Можно перенести это в сценарий оболочки или функцию и параметризовать searchstr
(-v searchstr="$1"
).
Однако, если поля имеют переменную ширину - т.е. если данные изменяются, ширина полей может измениться - необходимо будет быть немного более умными и динамично определить ширину поля от осмотра первой строки. Учитывая, что одно поле называют OWNER_NAME
, с помощью подчеркивания я предполагаю, что пробелы не присутствуют в именах полей, таким образом, я могу предположить, что пробел разделяет имена полей.
С определенным, можно заменить BEGIN...
строка с этим кодом:
NR == 1 {
for (i = 2; i <= NF; i++)
FIELDWIDTHS=FIELDWIDTHS index($0" ", " "$i" ")-index($0" ", " "$(i-1)" ") " "
FIELDWIDTHS=FIELDWIDTHS "5" # assuming 5 is the width of the last field
next
}
Это посмотрит на поля на первой строке и вычислит ширину поля путем вычисления различия между положениями последующих полей для второго к последнему полю. Я предположил, что ширина последнего поля равняется 5, но я думаю, что можно просто поместить большое количество там, и это будет работать с тем, что перенесено.
Мы должны искать пространство прежде и после имени, чтобы гарантировать, чтобы мы не находили NAME
внутри OWNER_NAME
(или если было названное поле OWNER
), и вместо этого соответствуйте целому полю (мы также должны добавить пространство к $0
для обеспечения мы можем соответствовать пространству в конце, даже если не было ни одного там).
Вы могли стать более необычными так, чтобы можно было запросить именем поля вместо того, чтобы соответствовать только на $3
, но я оставлю это Вам.
$ cat test
[#] OWNER_NAME NAME SIZE
[6] Robottinosino Software 200
[42] Robottinosino Ideas worth zero 188
[12] Robottinosino Ideas worth zero or more 111
[13] I am Batman Hardware 180
[25] Robottinosino Profile Pictures 170
$ cat test.sh
#!/bin/bash -
awk -F"\t" '(NR<=1){for(i=1;i<NF;i++) if(toupper("'$1'")==toupper($i)) field=i;} (toupper($field) == toupper("'"$2"'")){print $1}'
$ cat test | ./test.sh NAME "Ideas worth zero"
[42]
Я не уверен, что разделитель является вкладкой. Но довольно легко изменить его с sed
. Например, sed 's/\s\s+/\t/g'
сделает задание.
Также можно указать любое другое поле, не только NAME
. Это найдет само число правого столбца.
В случае, если Вам будет нужен только третий сценарий столбца, будет намного легче.
PS. Я использовал его в своем собственном проекте, поэтому это кажется, имеет вполне больше функциональности, в которой Вы нуждаетесь.
upd. из-за разделителя не является строкой запуска изменения вкладки к
cat test | sed 's/\s\s\+/\t/g' | ./test.sh NAME "Ideas worth zero"
Это работает прекрасное на моем сайте.
-F
может взять полный regex, таким образом, Вы не должны даже использовать sed
.
– Kevin
25.06.2012, 14:45
$ cat test
[#] OWNER_NAME NAME SIZE
[6] Robottinosino Software 200
[42] Robottinosino Ideas worth zero 188
[12] Robottinosino Ideas worth zero or more 111
[13] I am Batman Hardware 180
[25] Robottinosino Profile Pictures 170
$ cat test.sh
#!/bin/bash -
awk -F"\t" '(NR<=1){for(i=1;i<NF;i++) if(toupper("'$1'")==toupper($i)) field=i;} (toupper($field) == toupper("'"$2"'")){print $1}'
$ cat test | ./test.sh NAME "Ideas worth zero"
[42]
Я не уверен, что разделитель является вкладкой. Но довольно легко изменить его с sed
. Например, sed 's/\s\s+/\t/g'
сделает задание.
Также можно указать любое другое поле, не только NAME
. Это найдет само число правого столбца.
В случае, если Вам будет нужен только третий сценарий столбца, будет намного легче.
PS. Я использовал его в своем собственном проекте, поэтому это кажется, имеет вполне больше функциональности, в которой Вы нуждаетесь.
upd. из-за разделителя не является строкой запуска изменения вкладки к
cat test | sed 's/\s\s\+/\t/g' | ./test.sh NAME "Ideas worth zero"
Это работает прекрасное на моем сайте.
Вероятно, самое простое для фильтрации строк сначала 'Идеями, стоящими нуля, затем бросающего строки '... или больше':
grep 'Ideas worth zero' | grep -v 'Ideas worth zero or more'
И получить число от того канала вход в:
cut -d' ' -f1 | tr -d ']['
Который сокращает первое поле (разграниченный пространством) и удаление squeare скобок.
Лучше всего был бы к тому, если можно немного изменить формат файла таким способом, которым он идет с надлежащими разделителями полей.
Вероятно, самое простое для фильтрации строк сначала 'Идеями, стоящими нуля, затем бросающего строки '... или больше':
grep 'Ideas worth zero' | grep -v 'Ideas worth zero or more'
И получить число от того канала вход в:
cut -d' ' -f1 | tr -d ']['
Который сокращает первое поле (разграниченный пространством) и удаление squeare скобок.
Лучше всего был бы к тому, если можно немного изменить формат файла таким способом, которым он идет с надлежащими разделителями полей.
Это может помочь Вам:
function my_command () {
sed -n $(cut -b22-48 1.txt |
grep -n "$1"' *$' |
cut -f1 -d: )p 1.txt \
| cut -d' ' -f1 | tr -d ']['
}
Это сокращает только соответствующий столбец из входа, ищет номер строки, где строка появляется, затем проводит эту строку и только сохраняет число в первом столбце от него.