Як видалити всі рядки, крім останнього, за допомогою редактора unix ed із bash-скрипту


2

У мене є такий файл bash під назвою "файл" (справжній робить щось корисне):

ed db/seeds.rb <<EOF
1,$-1d
a
123
456
.
w
q
EOF

Коли я запускаю "bash file", він не видаляє жодних рядків. Якщо я використовую 1dзамість 1,$-1dнього, видаляємо перший рядок.

Чому це не працює? Я легко міг би вирішити, але мені цікаво, чому це не працює.


ed призначений для інтерактивного запуску. Якщо ви не використовуєте expectчи подібне, інтерактивні частини не можуть бути написані в сценарії оболонки.
ernie

Якщо у вас частина сценарію виглядає так: ed file <<EOFСценарій виконує команду (у цьому випадку "ed") таким чином, що команда вважає, що наступні рядки вводяться інтерактивно. Це триває до тих пір, поки не зустрінеться рядок, що містить лише текст, що слідує за <<(EOF у цьому випадку). Я постійно користуюся цією функцією.
Фред Фінкл

tailє спеціальним інструментом для виконання цього завдання.
gronostaj

Знову ж таки, це просто простий приклад того, що я роблю в реальному застосуванні. Хвіст спрацював би, але це не моє питання. Йдеться про ред.
Фред Фінкл

До речі, @ernie, diff -eвиробляє edскрипт для перетворення file1 в file2 . edпідтримує неінтерактивне використання з 1-го дня, у 1970-х.
G-Man

Відповіді:


0

Проблема полягає в тому, що оболонка інтерпретує команду $in 1,$-1d. (Зокрема, в моїх тестах це трактується $-як колекція setпрапорів.) Найкращий спосіб виправити це - цитувати або вийти з EOFрядка, як у

ed db/seeds.rb <<\EOF

або

ed db/seeds.rb <<"EOF"

Крім того, ви можете втекти (тобто поставити зворотній кут навпроти) кожен $у своєму "тут документі".


Я зіткнувся з тією ж проблемою саме зараз, і це було в контексті, який було легше зрозуміти. Я раніше використовував рішення про втечу долара (але, очевидно, не пам'ятав), але ніколи не знав альтернативи, яку ви запропонували. Менш болісні альтернативи. Дякую.
Фред Фінкл

У своєму коментарі Бармар добре зазначає : якщо ви хочете, ви можете використовувати змінні оболонки у вашому "тут документі". У такому випадку вам не слід цитувати або уникати EOFрядка, а просто уникати $s, з яким ви хочете досліджуватися буквально (залишаючи посилання змінної, наприклад $HOME,, в спокої).
G-Man

Дякуємо за нагадування. Я не використовую змінних оболонок дуже часто. Знаки долара зазвичай сьогодні з'являються в коді angularjs.
Фред Фінкл

1

sedв цьому випадку простіше. Виберіть один із:

sed -i -n '$p' file
sed -i '$!d' file

Помилка вашого коду полягає в тому, що оболонка розширюється $-перед передачею сценарію до ed. Це спрацює:

# quoting the heredoc word:
ed db/seeds.rb <<'EOF'
1,$-1d
w
q
EOF

На жаль, в реальному використанні я додаю рядки тексту після того, як видалив те, що вже було.
Фред Фінкл

@FredFinkle потім додайте до файлу.
gronostaj

Якщо справжній додаток потребує посилання на змінні в документі here-doc, ви можете використовувати <<EOFта уникати буквальних знаків долара за допомогою зворотного нахилу.
Barmar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.