Как удалить идентичные строки в одном файле от другого, с помощью sed?

Я обычно монтирую каталог через ssh через FUSE и sshfs.

Смонтируйтесь:

$ sshfs name@server:/path/to/dir /path/to/mount/point

Размонтирование:

$ fusermount -u /path/to/mount/point
4
15.02.2016, 19:11
3 ответа

Вот мой отрывок:

remove_lines()
{
    # remove lines from a file 
    #  
    # $1 - source file with patterns of lines to be removed
    # $2 - destination file
    tmpfile=$(mktemp "$(dirname -- "$2")"/XXXXXXXX) &&
    grep -F -f "$1" -v -- "$2" >>"$tmpfile" &&
    mv -- "$tmpfile" "$2" &&
}

Править: Я только что понял, что существует нет sed в нем, но это не было очень важно, не так ли?

8
27.01.2020, 20:47
  • 1
    Вы могли бы хотеть использовать mktemp для генерации временного имени файла, вместо tmp-$(uuidgen) или подобные взломы. –  Riccardo Murri 20.06.2011, 16:06
  • 2
    OP предположил, что sed был необходим, но не указывал, почему другое решение будет недопустимо. +1. –  Kevin M 20.06.2011, 16:40
  • 3
    я использовал строку в Вашем сценарии как так: grep -F -f "uniq_failing_specs.txt" -v -- "all_specs.txt" >>"passing_specs.txt" –  thekingoftruth 16.10.2012, 14:36
  • 4
    в его ответе корректна; не используя -x Вы открываете это до неожиданного поведения из-за дефектной логики. прохладный –  Wildcard 16.03.2016, 13:43

Попробуйте следующий сценарий;

## $1 - Small File
## $2 - Large File

sed 's/^/\//; s/$/\/d/; s/\\/\\\\/g' $1 > $HOME/sed_scpt.txt
sed 's/\\/\\\\/g' $2 | sed -f $HOME/sed_scpt.txt > $HOME/desired_output.txt

## Alternatively, you could change the 2nd line with the following;
sed -f $HOME/sed_scpt.txt $2 > $HOME/desired_output.txt

Примечание: Я использовал GNU sed 4.2.1.

2
27.01.2020, 20:47

Ответ @rajish с использованием grep был закрыл, но кое-что пропустил: задан вопрос об удалении одинаковых строк . По умолчанию grep будет соответствовать строкам (частям строк).

POSIX grep имеет подходящий параметр:

-x
Учитывать только строки ввода, в которых используются все символы в строке, за исключением завершающей новой строки , чтобы соответствовать всей фиксированной строке или обычному выражение должно соответствовать строкам.

Учитывая это, для этого можно использовать grep :

cp -f -p input.txt input.txt~
grep -v -x -F -f input.pat input.txt~ >input.txt

где input.pat содержит строки, которые необходимо удалить, а input.txt файл, который нужно обновить.

Решение @nvarun с использованием sed имело аналогичную проблему, в дополнение к отсутствию экранирования символов / в файле шаблона. Этот пример работает для меня и ограничивает синтаксис POSIX sed :

cp -f -p input.txt input.txt~
sed -e 's/\([\/]\)/\\\1/g' -e 's/^/\/^/' -e 's/$/$\/d/' input.pat > input.sed
sed -f input.sed input.txt~ >input.txt

На всякий случай оба сохраняют исходный файл перед его обновлением ( POSIX cp ).

input.pat

first
this is second
second/third
second\third

input.txt

first
only first should match
this is not first
this is second
the previous line said this is second
first/second/third
second/third
first\second\third
second\third

Результат:

only first should match
this is not first
the previous line said this is second
first/second/third
first\second\third
2
27.01.2020, 20:47

Теги

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