Вы используете параметр -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
являются такими разреженными файлами.
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"
Чтобы расширить ответ @RoVo, вы можете использовать цикл for для повторения всех ваших запросов:
for term in "kwd1" "kwd2" "kwd3" "kwd4" "kwd5"; do
grep "$term" search_file.txt || echo "string"`
done
Поскольку запрошенный вывод, по-видимому, имеет одну строку вывода для каждой строки ввода, где строка просто копируется, если она совпадает, и заменяется, если нет, есть лучшие способы сделать это, чем чтение файла 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.