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

Вы редактируете /etc/passwd файл и изменение пользователи окружают от /bin/bash, или /bin/sh кому: /sbin/nologin

8
20.03.2018, 00:07
7 ответов

Можно использовать sed:

sed -i 's/^/your_string /' your_file

Благодаря Stephane и комментариям Marco, обратите внимание что -i опцией не является POSIX. POSIX способ сделать вышеупомянутое был бы

sed 's/^/your_string /' your_file > tmp_copy && mv tmp_copy your_file

или perl:

perl -pi -e 's/^/your_string /' your_file

Объяснение

Обе команды выполняют regex замену, заменяя начало строки (^) с Вашей желаемой строкой. -i переключатель в обеих командах удостоверяется, что файл редактируется на месте (т.е. изменения отражаются в файле вместо печатного к stdout).

sed должно быть доступным на любой совместимой POSIX ОС и perl должно быть доступным на большинстве современных Нельдов кроме, возможно, для тех, которые прошли усилие по удалению его.

8
27.01.2020, 20:08
  • 1
    Маленькое исправление: -i переключатель не редактирует файл на месте. Это создает новый файл и перезаписывает исходный после того, как это сделало (доказательство: изменения inode). Нет многих инструментов, которые на самом деле делают оперативное редактирование, которое является опасной операцией. Кроме того, так как Вы упоминаете POSIX, -i переключатель не обязателен для совместимого POSIX sed, это - функция некоторых конкретных реализаций. –  Marco 08.10.2013, 23:00
  • 2
    sed -i не POSIX. Это - GNU. FreeBSD sed имеет подобную опцию, но Вам нужно sed -i '' там. –  Stéphane Chazelas 08.10.2013, 23:01
  • 3
    @Marco я знаю это -i создает временную копию (вот почему, я сказал, что изменения отражаются в исходном файле); я подразумевал, что Вы получаете ту же семантику как оперативная замена. Проверьте, что обновленный ответ совместим POSIX. –  Joseph R. 08.10.2013, 23:06
  • 4
    Строго говоря изменения отражаются в новом файле с тем же именем как оригинал. –  Keith Thompson 09.10.2013, 02:17
  • 5
    я часто использую $$ (идентификатор процесса текущей оболочки) как часть временного имени файла; это избегает усилия по размышлению о гарантируемом уникальном имени каждый раз: command filename > filename.$$ && mv filename.$$ filename –  Keith Thompson 09.10.2013, 02:18

Я представляю использование решения awk предварительно ожидая строка “нечто”.

awk '{ print "foo", $0; }' input > output

awk является межплатформенным и доступным в любой системе POSIX. Это не делает оперативного редактирования. Если Вы хотите отредактировать файл, не создавая второй, необходимо будет использовать временный файл. Посмотрите Joseph sed ответ, это показывает синтаксис. Другой взлом должен использовать следующий синтаксис, который в основном создает временный файл с тем же именем файла как исходный файл.

{ rm file; awk '{ print "foo", $0 }' > file; } < file
4
27.01.2020, 20:08
  • 1
    reducto# wc -l foo '914 нечто' reducto# { rm foo ; awk '{ print "prepend" , $0 }' > foo } < foo > Это, кажется, не работает. Я пробовал, потому что перенаправление к оригиналу раздражало меня, но это даже не запустится. –  kurtm 08.10.2013, 23:45
  • 2
    Этот пример будет работать, если он будет использовать круглые скобки для внешней стороны, а не фигурных скобок. –  kurtm 08.10.2013, 23:49
:|paste -d'foo ' - - - - input > output

(просто ребячество, хотя Вы, вероятно, найдете, что это является самым быстрым из всех решений, отправленных здесь:-b).

Канонический путь:

sed 's/^/foo /' < input > output

Однако это не легко адаптировано к произвольным строкам. Например,

sed "s/^/$var /"

Только работы, если $var не содержит, &, \, / ни символы новой строки.

В том отношении,

export var
awk '{print ENVIRON["var"], $0}'

или

perl -pe '$_="$ENV{var} $_"'

работал бы лучше.

14
27.01.2020, 20:08

Можно избежать проблем оперативного редактирования с потоковыми инструментами при помощи инструмента, который обычно делает оперативное редактирование - редактор!

ex sample.txt -c "%s/^/foo /" -c wq

Существует дополнительное преимущество, что команды легки и очевидны для любого, кто является сведущим в одном истинном редакторе.

4
27.01.2020, 20:08

Можно использовать perl сделать это:

$ perl -pi -e 's/^/mystring /' afile.txt

Пример

Создайте файл примера.

$ seq 5 > afile.txt

$ cat afile.txt
1
2
3
4
5

Выполните вышеупомянутую команду:

$ perl -pi -e 's/^/mystring /' afile.txt

$ cat afile.txt
mystring 1
mystring 2
mystring 3
mystring 4
mystring 5
2
27.01.2020, 20:08
  • 1
    Perl, кажется, универсален в наше время, но в течение долгого времени это не было. И я держу пари, что существует пара редких вариантов UNIX там, которые решительно отказываются иметь жемчуг как часть основы. Что-то для знания. –  kurtm 08.10.2013, 23:41
  • 2
    @kurtm видит обсуждение здесь. По-видимому, AIX не имеет Perl по умолчанию и, ни делает встроенные системы. –  terdon♦ 08.10.2013, 23:53
  • 3
    @DavidSainty - это достаточно универсально. Q был отмечен с Bash, таким образом, мне чрезвычайно трудно вообразить систему, которая имеет Bash, но не Perl. Во всяком случае вот один из 5 ответов, несколько из других шоу, как использовать sed, Я показал, как использовать Perl.... не поиск священной войны по вопросу. –  slm♦ 09.10.2013, 00:01
  • 4
    @DavidSainty По-видимому только OpenBSD. Я предполагаю, что сделал предположение, так как Открытые люди склонны быть консервативными о том, что они позволяют в основе. OpenBSD окончательно имеет его в основе. –  kurtm 09.10.2013, 00:43
  • 5
    @slm: "Мне чрезвычайно трудно вообразить систему, которая имеет Bash, но не Perl". У меня есть несколько таких систем, находящихся на моем столе. (Они, оказывается, встроенные системы.) –  Keith Thompson 09.10.2013, 02:20

Просто использование Bash

 while IFS= read -r line; do echo "foo" "${line}" ; done  < input > Output

Использование Python

python -c "import sys; print 'foo '.join([ l for l in sys.stdin.readlines() ])" < input > Output

Если Вы хотите отредактировать оперативный

import fileinput
import sys

for line in fileinput.input(['inputfile'], inplace=True):
    sys.stdout.write('foo {l}'.format(l=line))

Ссылка

1
27.01.2020, 20:08
  • 1
    Почему это работает быстрее, чем awk? –  Rahul Patil 08.10.2013, 23:11
  • 2
    Это только собирается работать быстрее, чем awk на очень маленьких файлах. Поведение варьируется через реализации эха, и оно разделяет начальные и конечные пробелы и обрабатывает обратные косые черты особенно. –  Stéphane Chazelas 08.10.2013, 23:12
  • 3
    @StephaneChazelas Да. Вы на 100% корректны просто протестированные... paste.ubuntu.com/6210934 –  Rahul Patil 08.10.2013, 23:19
  • 4
    prefix () { while IFS= read -r REPLY; do printf "%s%s\n" "$1" "$REPLY"; done; } должно быть более корректным. –  Matt 08.10.2013, 23:34
  • 5
    Почему {}? Я думаю, что @Matt предлагал, чтобы Вы превратили его в именованную функцию, какой смысл {} без имени функции? –  terdon♦ 08.10.2013, 23:51

Или вы можете сделать следующее:

vi filename.txt

Esc (чтобы убедиться, что вы находитесь в режиме NORMAL), а затем введите следующую команду:

:1,$ s/^/mystring
-1
27.01.2020, 20:08

Теги

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