Как удалить строку с соответствующим шаблоном из другого файла? - PullRequest
0 голосов
/ 03 марта 2019

Я хочу удалить строки в FILE1, содержащий шаблон в FILE2.
Как мне это сделать с помощью shell / bash или Tcl?

Например:

ФАЙЛ1:

This is ECO_01  
This is ECO_02  
This is ECO_03  
This is ECO_04

ФАЙЛ2:

ECO_02  
ECO_04  

Вывод:

This is ECO_01   
This is ECO_03  

Ответы [ 4 ]

0 голосов
/ 05 марта 2019

Другое решение Tcl:

set fid [open file2 r]
set patterns [lmap line [split [read -nonewline $fid] \n] {string trim $line}]
close $fid

set fid [open file1 r]
set lines [split [read -nonewline $fid] \n]
close $fid

set wanted [lsearch -inline -all -regexp -not $lines [join $patterns "|"]]
puts [join $wanted \n]
This is ECO_01  
This is ECO_03  

Ссылка: lsearch Справочная страница

0 голосов
/ 03 марта 2019

Вам просто нужно использовать команду sed (как показано ниже) для удаления соответствующих строк из FILE1.

macOS:

for i in `cat FILE2.txt`
do
sed -i '' "/$i/d" FILE1.txt
done

Linux:

for i in `cat FILE2.txt`
do
sed -i '/$i/d' FILE1.txt
done
0 голосов
/ 03 марта 2019

В Tcl вы загружаете файл шаблонов и используете их для фильтрации.Вероятно, проще всего поддерживать основной поток фильтрации, переходящий от стандартного ввода к стандартному выводу;Вы можете легко перенаправить их из / в файлы.Поскольку вы, похоже, хотите использовать «is pattern is substring of» в качестве правила сопоставления, вы можете сделать это с помощью string first, что приведет к следующему коду:

# Load in the patterns from the file named by the first argument
set f [open [lindex $argv 0]]
set patterns [split [string trimright [read $f] \n] \n]
close $f

# Factor out the actual matching
proc matches {theString} {
    global patterns
    foreach pat $patterns {
        # Change the next line to use other matching rules
        if {[string first $pat $theString] >= 0} {
            return true
        }
    }
    return false
}

# Read all input lines and print all non-matching lines
while {[gets stdin line] >= 0} {
    if {![match $line]} {
        puts $line
    }
}

Я считаю полезным выделитьпроцедуры с такими ключевыми битами, как «соответствует ли эта строка любому из моих шаблонов?». Вы, вероятно, назвали бы приведенный выше код примерно так:

tclsh doFiltering.tcl patterns.txt <input.txt >output.txt
0 голосов
/ 03 марта 2019

Наиболее общим решением будет

$ grep -vf file2 file1

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

$ awk 'NR==FNR{a[$1]; next} !($NF in a)' file2 file1
...