Как удалить точный текст из текстового файла?

#bash

#bash

Вопрос:

У меня есть log.txt файл, который выглядит точно так же, как этот.

 2.txt
/home/test/2.txt
 

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

 if grep -Fxq "$var" log.txt
then
      result=$(grep -m2 "$var" log.txt | tail -n1 )
      mv $var $result
      grep -w $var log.txt > log.txt.tmp
fi
 

первые две строки работают, они перемещают файл обратно
в исходный каталог.

эта строка здесь

 grep -w $var log.txt > log.txt.tmp
 

помещает то, что я хочу удалить из log.txt во временный текстовый файл. Это неверно

Мне нужно удалить результат

 grep -w $var log.txt > log.txt.tmp
 

из log.txt файл, но, похоже, я не могу этого сделать

Я пытался удалить одно и то же содержимое из двух файлов, но это слишком медленно, и я не хочу сортировать каждый раз. Должен быть более простой способ. Спасибо.

В основном вывод будет выглядеть следующим образом.

 2.txt
/home/2.txt
3.txt
/home/3.txt
 

если они решат удалить 2.txt (который уже работает) новый log.txt файл будет

 3.txt
/home/3.txt
 

Я думаю, что в основном нужно искать log.txt и удалите имя файла и строку под ним.

 sed -i "/$var/d" log.txt
 

Я попробовал это, но он удаляет файлы с 1.txt в нем также, так что, если файл 11.txt это также устранит и это.

Комментарии:

1. Пожалуйста, добавьте желаемый результат для этого примера ввода в свой вопрос.

2. Итак sed -i "/$var/d" log.txt , IIUC

3. @daniu, который работает, к сожалению, он удаляет файлы с похожими именами, такими как 11.txt потому что 1.txt есть в нем 🙁

4. Затем сделайте sed -i "/^$var/d" log.txt . Это заставляет имя файла начинаться с переменной. Или, sed -i "/^$var$/d" log.txt чтобы сделать точное совпадение.

5. @Anubis это также удалит каталог под именем файла? поскольку он содержит имя файла в пути?

Ответ №1:

 if grep -Fxq "$var" log.txt
then
    result=$(grep -m2 "$var" log.txt | tail -n1 )
    echo mv $var $result
    sed -i '/'"${var//./\.}"'$/d' log.txt  # remove all the lines ending with $var value
fi
 

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

т. е. если $var=2.txt , то sed -i '/2.txt/d' log.txt совпадения и т.д. 2.txt 2atxt ..

${var//./\.} предназначен для экранирования символов точки, чтобы избежать вышеуказанных совпадений.


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

 sed -i '/^'"${var//./\.}"'$/, 1 d' log.txt
 

Это может помочь, если у вас есть строки, заканчивающиеся одним и тем же именем файла, которые вам не нужно удалять.

Комментарии:

1. да, это не изменяет содержимое файла при выполнении команды sed. Я даже прогнал его через терминал.

2. вы var правильно установили переменную?

3. да, var — это просто аргументы от пользователя, которые будут именами файлов, это просто в настоящее время для var в «$ @» do, который перебирает все аргументы в командной строке

4. Это должно работать в любой достаточно современной sed версии. Проверьте, печатает ли следующее 1 4 5 (удаление 2 3 ): seq 5 | sed '/2/, 1 d'

5. Лол, это действительно работает, но его все еще удаляют 11.txt потому что технически это все еще заканчивается 1.txt очень досадная ошибка:(