Как насчет
for file in *.txt; do
grep -A1 "@<TRIPOS>BOND" "$file" | grep -q SUBSTR && mv "$file" bad_files/
done
Это будет проходить через все .txt файлы в текущем каталоге (изменение на blob до любых совпадений с вашими файлами) и сохранение каждый как $file. Затем он выполнит поиск $file для @<TRIPOS>BOND и распечатает его и следующую строку. Это передается через следующий grep, который молча (-q) ищет SUBSTR, если он находит его, это означает, что строка после BOND равна SUBSTRUCTURE, а не цифра, которую вы хотите, чтобы она переместите текущий файл в папку bad_files.
Это не так просто:
find -type f -exec \
awk '/@<TRIPOS>BOND/{getline; \
if ($0 !~ /1 3 5 ar/){\
printf "mv %s /path/to/move/%s\n", FILENAME, FILENAME}}' {} \; \
| bash
Объяснение:
find -type f: Найти все файлы в текущем рабочем каталоге awk '/@<TRIPOS>BOND/{getline; \: найти строку внутри файла и перейдите к следующей строке if ($0 !~ /1 3 5 ar/){\: если следующая строка НЕ (!~), ваша желаемая «цифровая строка» printf "mv %s /path/to/move/%s\n", FILENAME, FILENAME}}' {} \; \: постройте команду mv и запустите ее ... | bash: ... bash и выполните его.Таким образом, команда будет mv всем файлом, который не связывает числовую строку с каталогом /path/to/move/.
Задача довольно проста с помощью awk. Вот мой пример. Я создал два файла file-nm (для не пропущенных) и file-m (для отсутствующих) и каталог moved для файлов, которые мы хотим переместить.
awk '/@<TRIPOS>BOND/ {getline; if ($0 == "@<TRIPOS>SUBSTRUCTURE" ) system("mv \""FILENAME"\" moved")}' file-nm file-m
Здесь мы найдем строку @<TRIPOS>BOND, переходим к следующей строке и проверяем, является ли эта строка @<TRIPOS>SUBSTRUCTURE. Если это так, мы делаем системный вызов с «mv» FILENAME файла, который был найден, и «перемещен» в качестве адресата. Вот результат:
$ ls
file-m file-nm moved
$ awk '/@<TRIPOS>BOND/ {getline; if ($0 == "@<TRIPOS>SUBSTRUCTURE" ) system("mv \""FILENAME"\" moved")}' file-nm file-m
$ ls
file-nm moved
$ ls moved
file-m
awk '/@<TRIPOS>BOND/,/@/ {getline; if ($_ ~ /^@/) {printf "%s:%s\n",$_,FILENAME; system ("mv \""FILENAME"\" <bad_files>/$(basename \""FILENAME"\")")} exit}' <file_name>
Пояснение
/@<TRIPOS>BOND/,/@/ Нам нужен только блок между @<TRIPOS>BOND и следующая строка, начиная с @ getline Прочитать следующую строку после @<TRIPOS>BOND if ($_ ~ /^@/) Проверить, если строка начинается с @ true Печать сообщенияprintf "%s:%s\n",$_,FILENAME
Переместить файл system ("mv \""FILENAME"\" <bad_files>/$(basename \""FILENAME"\")")
false Оставьте скрипт exit
Пояснение
$ cat foo
@<TRIPOS>ATOM
2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
@<TRIPOS>SUBSTRUCTURE
$ cat bar
@<TRIPOS>ATOM
2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
1 3 5 ar
@<TRIPOS>SUBSTRUCTURE
$ awk '/@<TRIPOS>BOND/,/@/ {getline; if ($_ ~ /^@/) {printf "%s:%s\n",$_,FILENAME; system ("mv \""FILENAME"\" \""FILENAME"\"_moved")} exit}' foo
@<TRIPOS>SUBSTRUCTURE:foo
$ awk '/@<TRIPOS>BOND/,/@/ {getline; if ($_ ~ /^@/) {printf "%s:%s\n",$_,FILENAME; system ("mv \""FILENAME"\" \""FILENAME"\"_moved")} exit}' bar
$ cat foo_moved
@<TRIPOS>ATOM
2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
@<TRIPOS>SUBSTRUCTURE
$ cat bar_moved
cat: bar_moved: No such file or directory