Regex для удаления строк в файле (ах), заканчивающихся одинаковыми или заданными буквами - PullRequest
1 голос
/ 20 сентября 2011

мне нужен bash-скрипт для mac osx , работающий следующим образом:

./script.sh * folder/to/files/ 
#
# or #
#
./script.sh xx folder/to/files/

Этот скрипт

  • читает список файлов
  • открыть каждый файл и прочитать каждую строку
  • , если строки заканчиваются одинаковыми буквами (режим '*') или пользовательскими буквами (' xx ')затем
    удалить строку и RE-SAVE file
  • резервную копию исходного файла

Мой первый подход сделать это:

#!/bin/bash

# ck init params
if [ $# -le 0 ]
then
  echo "Usage: $0 <letters>"
  exit 0
fi

# list files in current dir
list=`ls BRUTE*` 
for i in $list 
do 

  # prepare regex    
  case $1 in
       "*") REGEXP="^.*(.)\1+$";;
       *) REGEXP="^.*[$1]$";;
  esac    
  FILE=$i

  # backup file
  cp $FILE $FILE.bak

  # removing line with same letters
  sed -Ee "s/$REGEXP//g" -i '' $FILE
  cat $FILE | grep -v "^$"

done

exit 0

Но это не работает так, как я хочу ....

Что не так?
Как я могу исправить этот скрипт?


Пример:

$cat BRUTE02.dat BRUTE03.dat
aa
ab
ac
ad
ee
ef
ff
hhh
$

Если я использую '*', я хочу, чтобы все файлы, заканчивающиеся одинаковыми буквами , были чистыми.
Если я использую ' ff 'Я хочу, чтобы все файлы, оканчивающиеся на' ff ', были чистыми.


Ах, это на Mac OSx .Помните, что sed немного отличается от классического linux sed.

man sed

 sed [-Ealn] command [file ...]
 sed [-Ealn] [-e command] [-f command_file] [-i extension] [file

...]

ОПИСАНИЕ Утилита sed читает указанные файлы или стандартный ввод, если файлы не указаны, изменяяввод, как указано в списке команд.Затем ввод записывается в стандартный вывод.

 A single command may be specified as the first argument to sed. 

Несколько команд можно указать с помощью параметров -e или -f.Все команды применяются к входу в указанном порядке независимо от их происхождения.

 The following options are available:

 -E      Interpret regular expressions as extended (modern)

регулярные выражения, а не базовые регулярные выражения (BRE).Страница справочника re_format (7) полностью описывает оба формата.

 -a      The files listed as parameters for the ``w'' functions

создаются (или усекаются) перед началом любой обработки по умолчанию.Опция -a заставляет sed задерживать открытие каждого файла до тех пор, пока команда, содержащая связанную функцию `` w '', не будет применена к строке ввода.

 -e command
         Append the editing commands specified by the command

аргумент для списка команд.

 -f command_file
         Append the editing commands found in the file

command_file к списку команд.Команды редактирования должны быть перечислены в отдельной строке.

 -i extension
         Edit files in-place, saving backups with the specified

расширение.Если задано расширение нулевой длины, резервная копия не будет сохранена.Не рекомендуется давать расширение нулевой длины при редактировании файлов на месте, так как вы рискуете повредить или частично содержимое в ситуациях, когда дисковое пространство исчерпано, и т. Д.

 -l      Make output line buffered.

 -n      By default, each line of input is echoed to the standard

вывод после всехкоманды были применены к нему.Опция -n подавляет это поведение.

 The form of a sed command is as follows:

       [address[,address]]function[arguments]

 Whitespace may be inserted before the first address and the

функциональные части команды.

 Normally, sed cyclically copies a line of input, not including

ее завершающий символ новой строки, в пространство образца (если только после`` D ''), применяет все команды с адресами, которые выбирают это пространство шаблона, копирует пространство шаблона в стандартный вывод, добавляет новую строку и удаляет пространство шаблона.

 Some of the functions use a hold space to save all or part of the

шаблонное пространство для последующего поиска.

что-нибудь еще?
понятно, моя проблема?

спасибо.

Ответы [ 4 ]

1 голос
/ 20 сентября 2011
perl -ne '
    BEGIN {$arg = shift; $re = $arg eq "*" ? qr/([[:alpha:]])\1$/ : qr/$arg$/}
    /$re/ && next || print
'

Пример:

echo "aa
ab
ac
ad
ee
ef
ff" | perl -ne '
    BEGIN {$arg = shift; $re = $arg eq "*" ? qr/([[:alpha:]])\1$/ : qr/$arg$/}
    /$re/ && next || print
' '*'

производит

ab
ac
ad
ee
ef
1 голос
/ 21 сентября 2011

Возможная проблема:

  • Когда вы вводите * в командной строке, оболочка заменяет ее именем всех файлов в вашем каталоге.Ваш $1 никогда не будет равен *.

И некоторые советы:

  • Вы можете заменить заменить:

Это:

# list files in current dir
list=`ls BRUTE*` 
for i in $list 

С:

for i in BRUTE*
  • И:

This:

cat $ FILE |grep -v "^ $"

С:

grep -v "^$" $FILE

Кроме возможной проблемы, я не вижу ничего, что выпрыгнуло на меня.Что вы имеете в виду clean ?Можете ли вы привести пример того, как должен выглядеть файл до и после и как будет выглядеть команда?

1 голос
/ 20 сентября 2011

Я не слишком хорошо знаю оболочку bash, поэтому не могу оценить, что это за ошибка.
Это просто наблюдение регулярного выражения в его понимании (это может быть неправильно).

* режим regex выглядит нормально:
^.*(.)\1+$ that ended with same letters..

Но буквальный режим может не выполнять то, что вы думаете.
current: ^.*[$1]$ that ended with 'literal string'
Это не должно использовать класс символов,

Измените его на: ^.*$1$

Понимайте, что строка в $ 1 (до того, как она входит в регулярное выражение) должна быть экранирована
, если в ней есть какие-либо метасимволы регулярного выражения.

В противном случае вы намереваетесь иметь класс персонажа?

0 голосов
/ 23 сентября 2011

Это проблема!

grep '\(.\)\1[^\r\n]$' *

на MAC OSX, ( ) { } и т. Д. ... должны быть указаны !!!

Решено, спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...