Как написать сценарий командной строки, который будет проходить через каждую строку в текстовом файле и добавлять строку в конце каждого? [Дубликат]

Простой код работает для любого итеративного объекта, а не только из списков:

  & gt; & gt; & gt; & gt;  def empty (seq): ... try: ... return all (map (empty, seq)) ... кроме TypeError: ... return False ... & gt; & gt; & gt; & gt;  empty ([]) True & gt; & gt; & gt; & gt; & gt;  empty ([4]) False & gt; & gt; & gt; & gt;  empty ([[]]) True & gt; & gt; & gt; & gt;  empty ([[], []]) True & gt; & gt; & gt; & gt; & gt;  empty ([[], [8]]) False & gt; & gt; & gt; & gt; & gt;  empty ([[], (False для _ в диапазоне (0))]) True & gt; & gt; & gt; & gt; & gt;  empty ([[], (False для _ в диапазоне (1))]) False & gt; & gt; & gt; & gt;  empty ([[], (True для _ в диапазоне (1))]) False  

Этот код делает предположение, что все, что может быть повторено, будет содержать другие элементы, и не должно считаться листом в «дереве». Если попытка перебора объекта перестает работать, то это не последовательность и, следовательно, конечно, не пустая последовательность (при этом возвращается False ). Наконец, этот код использует тот факт, что все возвращают True , если его аргумент является пустой последовательностью.

86
задан slhck 30 October 2011 в 17:05
поделиться

5 ответов

Если ваш 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
137
ответ дан JakeGould 15 August 2018 в 17:18
поделиться
  • 1
    Спасибо, это сработало! – Jason Volkoz 19 May 2010 в 23:03
  • 2
    Почему вы touch временный файл? И я сделал бы команду sed условной на успех cp или оригинал мог быть потерян. – Dennis Williamson 20 May 2010 в 01:19
  • 3
    Я коснулся файла, чтобы быстро зарезервировать временное имя. Это может и не понадобиться. Я думаю, что вы правы в том, чтобы сделать команду sed условной для успеха CP. Почему бы не изменить код, чтобы сделать это исправление. Я не буду возражать! Твой, Том – Tom DeGisi 20 May 2010 в 01:50
  • 4
    Как насчет добавления строки до строки? – Oxwivi 24 January 2012 в 12:26
  • 5
    @Oxwivi: sed -e 's/^/string after each line/' -i filename $ означает конец строки. ^ означает начало строки. – Tom DeGisi 28 February 2012 в 17:43
  1. Pure POSIX shell и 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. Инструменты оболочки с использованием paste, yes, head & amp; wc:
    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file
    
    Обратите внимание, что paste вставляет символ Tab до $suffix.

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

1
ответ дан agc 15 August 2018 в 17:18
поделиться
  • 1
    Ни один из них не предпочтительнее sed, если только ресурсы не ограничены. – agc 9 August 2018 в 17:34

Sed немного уродлив, вы могли бы сделать это элегантно, как это:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar
-8
ответ дан hendry 15 August 2018 в 17:18
поделиться
  • 1
    Сбой для файлов с большим количеством строк, чем ограничение максимального аргумента оболочки. Попробуйте: cat foo | при чтении a; do echo $ {a} bar; или что-то вроде этого; в большинстве случаев это подходящая замена. – alex 19 May 2010 в 23:36
  • 2
    Он также терпит неудачу для строк с пробелами в них. – Dennis Williamson 20 May 2010 в 01:18
  • 3
    Э, нет, это не подводит Денис. максимальный предел аргумента оболочки? Крики, ты будешь подвешен. – hendry 20 May 2010 в 11:16
  • 4
    Да, это так: $ cat foo foo bar baz alex @ armitage: ~ $ для i в cat foo; do echo $ {i} bar; сделал foobar barbar bazbar, но после некоторых тестов я мог ошибаться в своих рассуждениях, но Деннис прав – alex 20 May 2010 в 22:36
  • 5
    @hendry Да, это не работает для строк с пробелами в них, таких как echo "foo bar" | (for i in `cat`; do echo ${i}bar; done), который печатает 2 строки, даже если вход 1 строка foo barcat чтение из stdin вместо файла не имеет для этого никакого различия) , – hyde 26 November 2013 в 13:18

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

$ lam filename -s "string after each line"
7
ответ дан martin clayton 15 August 2018 в 17: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
7
ответ дан Optimus Prime 15 August 2018 в 17:18
поделиться
  • 1
    Кроме того, чтобы добавить номера строк (как в моем случае), можно использовать переменную NR: awk '{print $0, NR}' – andrybak 29 June 2017 в 13:55
Другие вопросы по тегам:

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