Сначала мне нужно сделать немного фона, может быть, есть какое-то более простое решение, но посмотрим.
Итак, у меня есть файл в определенном формате (столбцы) и в порядке, который содержит имена документов. Этот файл содержит более 850000 строк. Моей первоначальной задачей было найти все документы, которые нужно удалить. Обычно эти документы имеют некоторое числовое значение в последнем столбце, как, например, VC99.
Поэтому моей задачей было удалить каждый документ, помеченный этим значением VC.
Документы начинаются с заглавных букв и имеют некоторое число в четвертом столбце, например 04. Чтобы определить, где заканчивается этот документ, мне нужно было найти строку, которая начинается с двух или более заглавных букв и имеет конкретное значение для столбца (равное или меньшее предыдущего) ,
Например, как вы можете видеть ниже, документ начинается с ABC 101 ... и его значение в четвертом столбце равно 04, а в последнем столбце он помечен как VC99, поэтому мне нужно удалить его из файла со всеми вложенными документами.
ABC 101 11/11 = R1A 04 BLABLABLA BLAAAA ASDDSASDA SADDA VC22!VC23!VC24!VC25!VC26!VC99!VC27!VC28!VC29!VC30
9476-ABC 555 55/55 B2Z
345 34-BGF 957 22/55 A 3 FREE ASDADADADADAD.
1551-YTR 101 41/15 A 4/3 FREE ADADADADADADADADADADADADA XP1
123 00-DFG 111 11 D 4/3 FREE ADASDADASDASDADADADAD
1/190 06-YTR 101 11 D 4/3 FREE ASDADADASD ADADADA ASDADADASDA ADSADADADA
BFD 290 01/28 = D4B 05 BLABLABLA
1095-ANT 290 01/28 G2Z
131 61-ANT 290 01/28 A 3 FREE SASDADADADADAD.
1551-ANT 290 01/27 A 4/3 FREE SASDADADAASDADADADADASDADADADADAD XP1
1/155 18-ANT 290 01/10 A 4/3 FREE ASDADADADADAD XP1
21/155 18-ANT 290 01/21 A 4/1 FREE ASDADADADADADASDADADADADAD
DFT 290 9985 = T4 03 BLOCK APCLOB XIG/DO
1095-DFG 290 9985 R2
1551-DFG 290 9985 B 1/7 FREE ASDADADADADAD
1/1551-DFG 290 9985 B 1/7 FREE FASDADADADADADARASDADADADADAD AASDADADADADADOB
2/155 18-DFG 290 9985 A 1/L FREE AASDADADADADAD PASDADADADADAD CASDADADADADAD ASDADADADADAD
1/190 83-DFG 290 9985 A 1/L FREE APASDADADADADADON PASDADADADADADL ASDADADADADAD ASDADADADADAD
131 61-DFG 290 9985 B 3 FREE SASDADADADADADPEC.
DZZB 987 2242 = F5Y 04 SOFTWARE UNIT APCLOBU XIG/DO
1095-DFGY 987 2242 R2A
190 55-DFGY 987 2242 J 1/2/7 FREE SASDADADADADADO.
155 14-DFGY 987 2242 D 2/7 FREE APASDADADADADADURV
2/109 26-DFGY 987 2242 B 3/7 FREE CHAASDADADADADADTION
5/109 26-DFGY 987 2242 D 3/7 FREE CHASDADADADADADRMAASDADADADADADON
190 73-DFGY 987 2242 B 3/7 FREE AASDADADADADADRAM
152 01-DFGY 987 2242 ----- B
ZXC 290 0004 = T5 03 FUNCTION BLOCK CAPPGEN XIG/D VC22!VC23!VC24!VC25!VC26!VC99!VC27!VC28!VC29!VC30
1095-DFG 290 0004 R2
2/155 18-DFG 290 0004 B 1/L FREE CAPASDADADADADADN
131 61-DFG 290 0004 B 3 FREE STRUASDADADADADADC.
1551-DFG 216 2530 B 4/1/7 FREE BLOASDADADADADADNTING
1/1551-DFG 216 2530 B 4/1/7 FREE BLOCASDADADADADADHART
1/190 83-DFG 216 1642 J 4/1/L FREE CALASDADADADADADTHASDADADADADADCASDADADADADADG
DFFT 987 9426 = D5W 02 SOFTWARE UNIT CAASDADADADADADNU XIG/DO
1095-DFGY 987 9426 DF2
190 55-DFGY 987 9426 E 1/2/7 FREE CAASDADADADADADAM
155 14-DFGY 987 9426 C 2/7 FREE CAPPASDADADADADADRV
3/109 26-DFGY 987 9426 C 3/7 FREE CHAASDADADADADADTION
4/109 26-DFGY 987 9426 C 3/7 FREE CASDADADADADADON
5/109 26-DFGY 987 9426 B 3/7 FREE CHASDADADADADADTION
190 73-DFGY 987 9426 D 3/7 FREE CAASDADADADADADAM
152 01-DFGY 987 9426 ZX4 B
1/1521-DFGY 987 9426 C 3/7 FREE BLASDADADADADADASDADADADADADASDADADADADADINT
2/152 83-DFGY 987 9426 B 3/7 FREE BAASDADADADADADDADADADADASDADADADADADPORASDADADADADADPGEN
В этом примере каждая строка, начиная с ABC 101 11/11 до DFT 290 9985, должна быть удалена.
И затем снова все, начиная с ZXC 290 0004 до DFFT 987 9426 должно быть удалено.
По сути, мы можем сказать, что я хочу удалить что-нибудь между двумя шаблонами, и вот как я начал.
Моя общая идея состояла в том, чтобы извлечь все имена документов, отмеченные VC99, со значением из четвертого столбца, и я сделал это с помощью этой команды
grep "^[A-Z][A-Z].*=.*0[0-7].*V.[9-9][9-9].*" base.txt | awk -F "\t" {'printf ("%5s\t%s\n", $1, $4)'} > delete
В этот момент у меня был файл с именем delete с двумя значениями имени документа и присвоенного ему значения, и он выглядит так
ABC 101 11/11 04
ZXC 290 0004 03
К сожалению, многие имена содержат косые черты, поэтому я не мог легко передать их моей следующей команде awk, и это был первый удар на дороге, но я нашел решение для этого.
Я использовал sed, чтобы экранировать косые черты несколько раз, чтобы сработала следующая команда awk.
sed 's#/#\\\\/#g' delete > delete_fixed
Теперь мой исправленный файл выглядел так
ABC 101 11\\/11 04
ZXC 290 0004 03
Теперь я смог передать эти переменные в awk и найти шаблон, используя этот маленький скрипт, который я частично нашел на этом портале.
while IFS=$'\t' read var1 var2
do
awk -F "\t" '/^'"$var1"'/{flag=1;print;next}/^[A-Z][A-Z]/ && ($4 <= '"$var2"'){flag=0}flag' base.txt >> output
done < delete_fixed
После нескольких тестов я был уверен, что у меня есть полный список строк, которые мне нужно удалить из моего base.txt, который для этого примера выглядит следующим образом
ABC 101 11/11 = R1A 04 BLABLABLA BLAAAA ASDDSASDA SADDA VC22!VC23!VC24!VC25!VC26!VC99!VC27!VC28!VC29!VC30
9476-ABC 555 55/55 B2Z
345 34-BGF 957 22/55 A 3 FREE ASDADADADADAD.
1551-YTR 101 41/15 A 4/3 FREE ADADADADADADADADADADADADA XP1
123 00-DFG 111 11 D 4/3 FREE ADASDADASDASDADADADAD
1/190 06-YTR 101 11 D 4/3 FREE ASDADADASD ADADADA ASDADADASDA ADSADADADA
BFD 290 01/28 = D4B 05 BLABLABLA
1095-ANT 290 01/28 G2Z
131 61-ANT 290 01/28 A 3 FREE SASDADADADADAD.
1551-ANT 290 01/27 A 4/3 FREE SASDADADAASDADADADADASDADADADADAD XP1
1/155 18-ANT 290 01/10 A 4/3 FREE ASDADADADADAD XP1
21/155 18-ANT 290 01/21 A 4/1 FREE ASDADADADADADASDADADADADAD
ZXC 290 0004 = T5 03 FUNCTION BLOCK CAPPGEN XIG/D VC22!VC23!VC24!VC25!VC26!VC99!VC27!VC28!VC29!VC30
1095-DFG 290 0004 R2
2/155 18-DFG 290 0004 B 1/L FREE CAPASDADADADADADN
131 61-DFG 290 0004 B 3 FREE STRUASDADADADADADC.
1551-DFG 216 2530 B 4/1/7 FREE BLOASDADADADADADNTING
1/1551-DFG 216 2530 B 4/1/7 FREE BLOCASDADADADADADHART
1/190 83-DFG 216 1642 J 4/1/L FREE CALASDADADADADADTHASDADADADADADCASDADADADADADG
И, как вы можете предположить, судя по плитке, я застрял.
Я не знаю, как удалить эти точные строки из моего файла base.txt.
Я пробовал grep
grep -F -x -v -f output base.txt > final
но он слишком жадный и удаляет слишком много, возможно, из-за дубликатов.
Хуже всего то, что я не могу ни отсортировать этот файл, ни изменить его структуру, потому что этот файл будет импортирован в другой инструмент, поэтому я могу удалить только строки.
Я также пробовал использовать diff, чтобы увидеть только различия, но в диссе добавляются некоторые символы и изменяется структура (или я не знаю, как правильно его использовать).
Моя идея состоит в том, чтобы как-то начать удаление со строки, которая сначала точно совпадает, а затем перейти вниз и не возвращаться к началу файла или что-то в этом роде. Или, может быть, есть способ сделать это вместе с моим поиском по шаблону awk?
Буду благодарен за любые советы на данный момент.