Печать строки, когда grep не получает совпадений

Вы используете параметр -s для ls .

Размер файла и объем занимаемого дискового пространства могут отличаться. Представьте, например, что если вы открываете новый файл, ищите в нем 1 ГБ и что-то записываете, ОС не выделяет 1 ГБ (плюс место для чего-то) на диске, она выделяет только то же самое для чего-то - это называется " разреженный файл ".

Я написал небольшую программу на C для создания такого файла:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int fd = open("/tmp/foo.dat", O_CREAT | O_WRONLY, 0600);

    if (fd > 0) {
        const off_t GIG = 1024 * 1024 * 1024;

        // Seek 1G into the file
        lseek(fd, GIG, SEEK_SET);

        // Write something
        write(fd, "hello", sizeof "hello");

        close(fd);
    }

    return 0;
}

Запустив эту программу, я получаю:

$ ls -lh /tmp/foo.dat
-rw------- 1 user group 1.1G Feb  4 15:25 /tmp/foo.dat

Но используя -s , я получаю:

$ ls -sh /tmp/foo.dat
4.0K /tmp/foo.dat

Итак, был выделен блок размером 4 КБ. на диске, чтобы сохранить "привет" (а 4К - это наименьшая единица выделения для моей файловой системы).

В вашем случае похоже, что app и web являются такими разреженными файлами.

5
29.04.2019, 15:55
3 ответа

grepзавершает работу с ненулевым -кодом, когда ничего не найдено.

Изman grep:

Normally the exit status is 0 if a line is selected, 1 if no lines were selected, and 2 if an error occurred.

Таким образом, вы можете использовать:

grep kwd3 search_file.txt || echo "string"
15
27.01.2020, 20:32

Чтобы расширить ответ @RoVo, вы можете использовать цикл for для повторения всех ваших запросов:

for term in "kwd1" "kwd2" "kwd3" "kwd4" "kwd5"; do
    grep "$term" search_file.txt || echo "string"`
done
0
27.01.2020, 20:32

Поскольку запрошенный вывод, по-видимому, имеет одну строку вывода для каждой строки ввода, где строка просто копируется, если она совпадает, и заменяется, если нет, есть лучшие способы сделать это, чем чтение файла 5 раз и распечатать строки в том порядке, в котором они находятся в файле поиска _kwd.sh, а не во входном файле.

Вместо этого вы должны обрабатывать входной файл по одной строке за раз. Есть много инструментов, которые могут это сделать. Например

#!/bin/sh
sed -e '/kwd1/{p;d}
        /kwd2/{p;d}
        /kwd3/{p;d}
        /kwd4/{p;d}
        /kwd5/{p;d}
        s/.*/string/' search_file.txt

в котором говорится, что для каждого совпадающего ключевого слова распечатайте строку, затем отбросьте ее и перейдите к следующей строке. Если он проходит через все ключевые слова и ни одно из них не соответствует, измените строку на строку (и затем неявно напечатайте ее ).

Вы можете использовать awkс чем-то вроде этого

 #!/bin/sh
 awk '{ if (/kwd1|kwd2|kwd3|kwd4|kwd5/) { print } else {print "string" }}' search+file.txt

У вас может быть чистая реализация оболочки

 #!/bin/sh
 while read -r line
 do
     case "$line" in
     (*"kwd1"*|*"kwd2"*|*"kwd3"*|*"kwd4"*|*"kwd5"*) printf '%s\n' "$line" ;;
     (*) printf '%s\n' "string" ;;
     esac
 done < search_file.txt

Вы также можете использовать perl, ruby, python.

0
27.01.2020, 20:32

Теги

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