sed удалить строку, содержащую строку и ничего кроме; автоматизация использования для цикла - PullRequest
1 голос
/ 25 июля 2011

Q1: Sed задает всю строку, и, если строка не что иное, как строка, удалите


У меня есть файл, который содержит несколько следующих чисел:

1 1
3 1
12 1
1 12
25 24
23 24

Я хочу удалить одинаковые номера в каждой строке.Для этого я либо использовал: sed '/1 1/d' < old.file > new.file ИЛИ sed -n '/1 1/!p' < old.file > new.file

Вот основная проблема.Если я ищу шаблон «1 1», это означает, что я избавляюсь и от «1 12».Так что я хочу, чтобы шаблон указывал всю строку, и если это так, удалял ее.

Q2: Автоматизация вопроса 1


Я также пытаюсь автоматизировать эту проблему.Диапазон чисел в первом и втором столбцах может быть от 1 до 25.

Пока что это то, что я получил:

for ((i=1;i<26;i++)); do
 sed "/'$i' '$i'/d" < oldfile > newfile; mv newfile oldfile;
done

Это никак не влияет на старый файл вконец.(

Ответы [ 3 ]

1 голос
/ 25 июля 2011

Просто поместите первый номер в группу (\([0-9]*\)), а затем найдите его с обратной ссылкой (\1).Поскольку строка для удаления должна содержать только , группа повторяется, используйте ^, чтобы отметить начало строки, и $, чтобы отметить конец строки.Например, для следующего файла:

$ cat input 
1 1
3 1
12 1
1 12
12 12
12 13
13 13
25 24
23 24

... результат:

$ sed '/^\([0-9]*\) \1$/d' input 
3 1
12 1
1 12
12 13
25 24
23 24
1 голос
/ 25 июля 2011

Это было бы более читабельно с awk:

awk '$1 == $2 {next} {print}' oldfile > newfile

Обновление на основе комментария:

Если требуется удалить строки, в которых два значения находятся в пределах 1 друг от друга:

awk '{d = $1-$2; if (-1 <= d && d <= 1) next; else print}' oldfile

К сожалению, у awk нет abs() (по крайней мере, у nawk и gawk нет)

0 голосов
/ 25 июля 2011

Вы также можете сделать это с помощью команды grep:
grep -E -v "([0-9])*\s\1" testfile

Найдите несколько цифр в строке и запомните их, затем один пробел, за которым следуют те цифры, которые вы помните.

...