Как в Bash добавить строку после каждой строки в файле?

113

Как добавить строку после каждой строки в файле с помощью bash? Можно ли это сделать с помощью команды sed, если да, то как?

Джейсон Волкоз
источник

Ответы:

188

Если вы sedразрешаете редактирование на месте с помощью -iпараметра:

sed -e 's/$/string after each line/' -i filename

Если нет, вам нужно создать временный файл:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename
Том ДеГизи
источник
Зачем тебе touchвременный файл? И я бы поставил sedкоманду в зависимость от успеха, cpиначе оригинал может быть утерян.
Приостановлено до дальнейшего уведомления.
Я прикоснулся к файлу, чтобы быстро зарезервировать временное имя. Возможно, в этом нет необходимости. Я думаю, вы правы, когда ставите команду sed в зависимость от успеха cp. Почему бы не отредактировать код, чтобы исправить это. Я не буду возражать! С уважением, Том
Том ДеГизи
А как насчет добавления строки перед строкой?
Oxwivi
10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ означает конец строки. ^ означает начало строки.
Tom DeGisi
Если я подключаюсь к sed, sed 's/^/string after each line/'делает то , что я ожидал (добавляется к каждой строке), но sed 's/^/string after each line/'не делает (он заменяет всю строку моей строкой добавления). Что дает? Есть идеи @TomDeGisi?
philadams
18

Я предпочитаю использовать awk. Если есть только один столбец, используйте $0, иначе замените его последним столбцом.

В одну сторону,

awk '{print $0, "string to append after each line"}' file > new_file

или это,

awk '$0=$0"string to append after each line"' file > new_file
Оптимус Прайм
источник
1
Кроме того, для добавления номеров строк (как в моем случае) можно использовать NRпеременную:awk '{print $0, NR}'
andrybak
2
@optimus Я пробовал ваш метод, но получил дополнительное пространство между ними, есть идеи, как их удалить?
Адил Саджу
@AdilSaju, sed 's/ //g'это сработало для моего требования, но оно удалит пробел в каждой строке, вот какой вариант gдля и везде в строке.
Eklavyaa
@AdilSaju, пожалуйста, добавьте подробности. Лучше задать новый вопрос.
Оптимус Прайм
@AdilSaju awk Удалить , лайк {print $0"string to append after each line"}.
Culip
8

Если он у вас есть, утилита lam (ламинат) может это сделать, например:

$ lam filename -s "string after each line"
Мартин Клейтон
источник
5
  1. Чистая оболочка POSIX и sponge:

    suffix=foobar
    while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
    sponge file
    
  2. xargsи printf:

    suffix=foobar
    xargs -L 1 printf "%s${suffix}\n" < file | sponge file
    
  3. Использование join:

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
    
  4. Инструменты Shell , используя paste, yes, head и wc:

    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file
    

    Обратите внимание, что перед этим pasteвставляется символ табуляции$suffix .

Конечно, spongeможно заменить временным файлом, а затем mvповерх исходного имени файла, как и некоторые другие ответы ...

АРУ
источник
1
Ни один из них не является предпочтительным sed, если ресурсы не очень ограничены.
agc
Мне нравится решение без использования sed. sedне нужен для такой простой работы.
Брюс
1

Я предпочитаю echo. используя чистый bash:

cat file | while read line; do echo ${line}$string; done
欢乐 的 Xiaox
источник
-9

Сед немного уродлив, изящно это можно сделать так:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar
Хендри
источник
2
Не работает для файлов с количеством строк, превышающим максимальное значение аргумента оболочки. Попробуйте: cat foo | пока читал; сделать echo $ {a} bar; сделано или что-то в этом роде; в большинстве случаев это подходящая замена для.
Alex
1
Он также не работает для строк с пробелами в них.
Приостановлено до дальнейшего уведомления.
1
Э, нет, Деннис не подводит. максимальный предел аргумента оболочки? Крики, ты напуган.
hendry
Да, есть: $ cat foo foo bar baz alex @ armitage: ~ $ for i in cat foo; сделать echo $ {i} bar; done foobar barbar bazbar, но после некоторых тестов я могу ошибаться в своих рассуждениях, но Деннис прав
Алекс
3
@hendry Да, это не работает для строк с пробелами в них, например, echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)который печатает 2 строки, даже если ввод - 1 строка foo barcatчтение из стандартного ввода вместо файла не имеет значения для этого).
hyde