От man grep
:
Управление строкой контекста
- ЦИФРА, - after-context=NUM
Распечатайте ЦИФРОВЫЕ строки запаздывающего контекста после согласующих отрезков длинной линии. Помещает строку, содержащую разделитель группы (-) между непрерывными группами соответствий. С-o или - только соответствующая опция, это не имеет никакого эффекта, и предупреждение дано.
- B ЦИФРА, - before-context=NUM
Распечатайте ЦИФРОВЫЕ строки ведущего контекста перед согласующими отрезками длинной линии. Помещает строку, содержащую разделитель группы (-) между непрерывными группами соответствий. С-o или - только соответствующая опция, это не имеет никакого эффекта, и предупреждение дано.
- C ЦИФРА, - ЦИФРА, - context=NUM
Распечатайте ЦИФРОВЫЕ строки выходного контекста. Помещает строку, содержащую разделитель группы (-) между непрерывными группами соответствий. С-o или - только соответствующая опция, это не имеет никакого эффекта, и предупреждение дано.
Посмотрите, как легкий, который был? man
Ваш друг.
с Perl:
perl -e 'my @lines = <>; print for @lines[0, $#lines, 1..$#lines-1]' file
с awk:
$ awk '
{lines[NR]=$0}
END{
print lines[1], lines[NR];
for (i=2; i<NR; i++) {print lines[i]}
}
' OFS=$'\n' file
выход
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Наивное одобрение с помощью awk:
~$ awk '{a[NR]=$0}END{print a[1];print a[NR];for(i=2;i<NR;i++){print a[i]}}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Вы сохраняете каждую строку в массиве a
, затем распечатываете массив в нужном вам порядке (1-я строка, последняя (NR
) и от 2 до предпоследней.
Используя комбинацию "голова/хвост" и "сед:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Выведите первую строку, последнюю, и с помощью "сед" удалите первую и последнюю.
С помощью только sed я смог найти только эту команду. Я уверен, что существуют лучшие способы:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Если это первая строка, то распечатайте ее (по умолчанию).
Из второй строки поместите его в буфер удержания(H
), и удалите из пространства шаблона (d
).
А если это последняя строка, выведите ее (p
), затем получите буфер удержания (x
), удалите пустую строку (s/^\n///
) и выведите ее (p
).
Наиболее вероятно различие в переменных среды и текущей рабочей папке. Служба
запускает скрипт из /
и с чистой средой. Таким образом, может потребоваться проверить среду и текущий рабочий каталог (с помощью команд export
, pwd
или set
) и добавить отсутствующие предварительные условия в сценарий.
Вы близки.
Во-первых, переменная M4
должна быть набором к пути к фактическому файлу программы M4, а не к каталогу, в котором она находится. Возможно, для этой переменной чаще, чем в вашем случае, используется выбор нескольких M4 программ, которые уже находятся в PATH
, поэтому необходимо назвать фактический исполняемый файл. Обычно в OSes типа BSD используется платформа m4
, а затем программа GNU M4, называемая, например, gm4
. При построении GNU Bison может потребоваться использовать GNU-версию M4, и эта переменная позволяет это сделать. В противном случае сценарий сначала найдет версию BSD в нашей примерной системе.
Во-вторых, я думаю, что ваше изменение PATH
игнорируется. Если не экспортировать
PATH
, новое значение будет доступно только оболочке. Это можно исправить двумя способами:
export PATH=$HOME/local/flex/bin/:$PATH
или
PATH=$HOME/local/flex/bin/:$PATH ../configure --flags-and-stuff-here
Вторая версия вносит изменения только для сценария configure
. Любые программы, запускающие скрипты, не увидят измененный PATH
, если он не экспортирует новое значение.
Лично я бы сделал это первым способом в одном из ваших сценариев запуска (например, ~/.bash _ profile
), потому что вы хотите, чтобы ваша личная версия Flex была доступна вам после установки Bison. Регистрация, затем вернитесь и попробуйте запустить flex
для тестирования. Если это работает, скрипт Bison configure
также должен сначала найти эту версию.
Эта проблема на самом деле может быть проще всего сделать с ed
, поскольку это в основном скриптовый текстовый редактор, а не потоковый процессор. Используя ed
, вы не должны сохранять все строки файла в массив, например, так как он уже делает это для вас.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
...который будет H
ставить каждую строку, которая является !
не первая, а первая его p
рint. На последней строке $
ex
меняет удержание и пробелы шаблонов до делает H
старую - которая получает сохраненные строки, прикрепленные к последней строке - тогда d
eletes из выводимых строк все строки, которые являются !
не $
последняя.
На последней строке $
ex
снова меняет пробелы, s///
отбрасывает первый \n
ewline символ - который заботится о лишнем добавленном на второй строке - затем автоматически распечатывает лот.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
...просто для сохранения вашего примера в реальный файл....
sed '1p;$!d;r infile' <infile | sed '3d;$d'
, который перенаправляет sed
stdin
, который только p
прорисовывает первую строку до d
eleting из вывода всех строк, которые являются !
, а не $
последняя. Последняя строка распечатана автоматически, но это также единственная строка, на которой выполняется последняя команда - которая должна r
снова вывести весь infile
на stdout
. Все это передается по трубе |
во вторую sed
, которая затем должна только d
elete из своего выхода свою третью и последнюю входную линию, чтобы завершить перестановку.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd