Найти файлы с определенным 2-строчным шаблоном, используя awk

У меня есть несколько сотен файлов с таким шаблоном

@<TRIPOS>ATOM
  2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
 1  3  5  ar
@<TRIPOS>SUBSTRUCTURE

, в некоторых файлах отсутствует строка после @<TRIPOS>BOND, и они выглядят как

@<TRIPOS>ATOM
  2 H18 65.2220 Du 1 RES1 0.0000
@<TRIPOS>BOND
@<TRIPOS>SUBSTRUCTURE

Я пытаюсь найти все файлы в моем рабочем каталоге, в которых отсутствует числовая строка после @<TRIPOS>BOND, и переместить их в другой каталог. Я знаю, что это простая задача, но я новичок в Linux.

Примечание: файлы различаются по длине и номерам строк, поэтому я «подбираю» строку после строки @<TRIPOS>BOND.

Вот один из моих кодов, которые я планировал написать в цикле for. Это не делает работу, но я показываю это, чтобы показать одно из моих испытаний.

cat file | grep -A1 '@<TRIPOS>BOND' | awk 'FNR == 2 {print}'

Спасибо

3
задан 7 May 2014 в 13:38

6 ответов

Если Ваша версия grep поддерживает режим PCRE (-P) Вы могли попробовать многострочное соответствие, которое находит экземпляры @<TRIPOS>BOND это сопровождается (только после новой строки) @<TRIPOS>SUBSTRUCTURE например.

grep -lzP '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' *

\Q и \E может быть ненужным в этом случае, но предназначаются для принуждения литерала, соответствующего (в случае, если @, >, < имейте особое значение в Perl regex синтаксис). -l говорит grep перечислять файлы соответствия вместо того, чтобы печатать соответствие. Можно затем использовать список файлов как вход к mv команда, например.

grep -lzP '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' * | xargs mv -t /path/to/newdir/


Дополнительная информация

Вы могли выразить вторую часть соответствия как предвидение, но я не думаю, что это имеет преимущество в этом случае

grep -lzP '\Q@<TRIPOS>BOND\E\n(?=\Q@<TRIPOS>SUBSTRUCTURE\E)' *

Эквивалентные выражения в pcregrep (который не является частью стандартной системы Ubuntu, но доступный из репозитория) было бы что-то как

pcregrep -lM '\Q@<TRIPOS>BOND\E\n\Q@<TRIPOS>SUBSTRUCTURE\E' *

и

pcregrep -lM '\Q@<TRIPOS>BOND\E\n(?=\Q@<TRIPOS>SUBSTRUCTURE\E)' *
6
ответ дан 7 May 2014 в 13:38

Как насчет

for file in *.txt; do 
    grep -A1 "@<TRIPOS>BOND" "$file" | grep -q SUBSTR && mv "$file" bad_files/
done

Объяснение:

Это циклично выполнится через все .txt файлы в текущем каталоге (изменяют на блоб к любым соответствиям Ваши файлы) и сохраняют каждого как $file. Это будет затем искать $file для @<TRIPOS>BOND и печать это и следующая строка. Это передается через следующее grep который тихо (-q) ищет SUBSTR, если это находит его, это означает что строка после BOND SUBSTRUCTURE а не числовая строка Вы хотите так, она переместит текущий файл в папку bad_files.

3
ответ дан 7 May 2014 в 13:38

Дело не в этом простой:

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:... колотите и выполните его.

Таким образом, команда будет mv весь файл, которые не являются contianing числовая строка к названному каталогу /path/to/move/.

0
ответ дан 7 May 2014 в 13:38
nawk '/^@<TRIPOS>BOND/{getline;if( $0 ~ /^@/){print "mv", FILENAME, "../NewLoc/"}}' * | bash
0
ответ дан 7 May 2014 в 13:38

Задачей является довольно простое использование 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 "ИМЯ ФАЙЛА файла, который был найден, и" переместился" как место назначения. Вот результат:

$ 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
0
ответ дан 7 May 2014 в 13:38

Используя awk или gawk

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 ($_ ~ /^@/)

    Проверьте, если строка запускается с a @

    • 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
0
ответ дан 7 May 2014 в 13:38

Другие вопросы по тегам:

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