Действительно ли возможно с Gedit или командной строкой изменить каждую четвертую строку текстового файла?

Я пытаюсь преобразовать текстовый файл в разделенную электронную таблицу вкладки. Мой текстовый файл - что-то вроде этого:

Dog
Cat
Fish
Lizard
Wolf
Lion
Shark
Gecko
Coyote
Puma
Eel
Iguana

Со стандартным поиском и функции замены в Gedit или LibreOffice, это - замена easyto конец строки с вкладкой. Но если я просто подкачаю возвраты каретки для вкладок, то я получу это:

Dog   Cat   Fish   Lizard   Wolf   Lion   Shark   Gecko   Coyote   Puma   Eel   Iguana

Но то, что я должен сделать, заставляют это быть похожим на это:

Dog   Cat   Fish   Lizard
Wolf   Lion   Shark   Gecko  
Coyote   Puma   Eel   Iguana

Так, я могу подкачать каждый конец символа строки для вкладки за исключением каждой четвертой строки?

Я не знаю, может ли такое условное повторение быть сделано с регулярными выражениями в программе как Gedit или LibreOffice, поэтому возможно, это должно быть некоторой функцией командной строки? Я даже не ясен на том, какой лучший инструмент для запуска с.


Обновление:

Я попробовал следующие команды:

sed 'N;N;N;s/\n/\t/g' file > file.tsv

paste - - - - < file > file.tsv

pr -aT -s$'\t' -4 file > file.tsv

xargs -d '\n' -n4 < inputfile.txt

Но когда я пытаюсь открыть получающееся tsv файл в LibreOffice, столбцы являются не совсем правыми. Я не уверен, означает ли это, что я не выполняю вышеупомянутые команды правильно, или если я делаю, что-то не так в LibreOffice импортирует функцию:

TSV opening in Calc

Только для ссылки, желаемый результат должен быть похожим на это:

Proper columns

11
задан 25 April 2018 в 05:49

8 ответов

Вы могли использовать редактора командной строки такой как sed

sed 'N;N;N;s/\n/\t/g' file > file.tsv

или более программно путем добавления символов продолжения строки обратной косой черты к каждой из строк Вы хотите присоединиться к использованию sed's GNU n skip m операция взятия адреса и после него с классической остротой для присоединения к длительным строкам:

sed '0~4! s/$/\t\\/' file | sed -e :a -e '/\\$/N; s/\\\n//; ta'

Посмотрите, например, Объясненные Остроты Sed:

  1. Добавьте строку к следующему, если она заканчивается обратной косой чертой "\".

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

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

paste - - - - < file > file.tsv

(количество - будет соответствовать числу столбцов), или

pr -aT -s$'\t' -4 file > file.tsv

(можно опустить -s$'\t если Вы не возражаете против вывода, который будет разделен несколькими вкладками).


Странное поведение переимпорта, которое Вы наблюдаете, состоит почти наверняка в том, потому что исходный файл имеет окончания строки Windows-style CRLF. Если необходимо работать с файлами из Windows, то можно прокрутить преобразование в команду различными способами, например.

tr -d '\r' < file.csv | paste - - - -

или

sed 'N;N;N;s/\r\n/\t/g' file.csv

Первый удалит ВСЕ возвраты каретки, тогда как последний сохранит CR в конце каждой из новых строк (который может быть тем, что Вы хотите, если намеченный конечный пользователь находится в Windows).

16
ответ дан 23 November 2019 в 03:49

Можно использовать xargs всегда группе четыре строки в одну, разделенную с одиночным пробелом каждый:

xargs -d '\n' -n4 < inputfile.txt

-d '\n' устанавливает входной разделитель на символ новой строки, иначе он также повредился бы на пробелах. Если у Вас только есть одно слово на входную строку так или иначе, можно даже опустить это.
-n4 определяет номер аргумента (количество входных параметров на выходную строку) к 4.

Вывод:

Dog Cat Fish Lizard
Wolf Lion Shark Gecko
Coyote Puma Eel Iguana

Или если Вы хотите вкладки как разделители вместо пространства, можно заменить их впоследствии. Однако, если бы у Вас были пробелы в Ваших входных строках, то они заменить также:

xargs -d '\n' -n4 | tr ' ' '\t'

Вывод (смотрят в зависимости от вкладки width браузера/терминала):

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana
13
ответ дан 23 November 2019 в 03:49

Вы могли также использовать:

awk -v ORS="" '{print $1; print NR%4==0?"\n":"\t"}' file > file.tsv 

Две awk встроенных переменные:

  • ORS: Произведите Разделитель записей (default=newline). Это добавляется в конце каждой команды печати.
  • NR: Количество текущей строки awk обрабатывает.

Эта команда, для каждой строки, отобразит содержание первого (и здесь только) столбец. Затем это принимает решение добавить новую строку или вкладку путем тестирования остатка от подразделения NR 4.

3
ответ дан 23 November 2019 в 03:49

Другой самый короткий awk подход:

awk '{printf $0 (NR%4?"\t":"\n")}' infile

Этот printf только один столбец, сопровождаемый следующим и следующим и... и Вкладка \t символ после каждого, но будет printf a \nсимвол ewline, когда Количество Записи было фактором 4 (где NR%4 возвратится 0 (ложь), которая является что Тернарный оператор condition(s)?when-true:when-false делает.)

3
ответ дан 23 November 2019 в 03:49

Мое решение этого состояло бы в том, чтобы использовать комбинацию sed и sed. Во-первых, Вы могли отметить каждую четвертую строку с некоторым специальным символом, например >, использование этого решения:

В этом случае Вы хотите начать со строки 5 и отметить каждую 4-ю строку после него. В GNU sed это может быть дано как адрес 5~4. Можно использовать эту команду:

sed '5~4s/^/>/' file1 > file2

Затем необходимо удалить новые строки, которые могут быть сделаны с a sed цикл:

sed ':a;N;s/\n/ /;ba' file2 > file3

Существуют более легкие способы преобразовать новые строки в некоторый другой символ, например, с tr:

tr '\n' ' ' < file2 > file3

Так или иначе объединение этих двух дает

Dog   Cat   Fish   Lizard   >Wolf   Lion   Shark   Gecko   >Coyote   Puma   Eel   Iguana

( sed версия оставляет запаздывающую новую строку, в то время как tr версия не делает),

После этого Вы должны только преобразовать специальные символы, которые Вы вставили в новые строки; посмотрите, например, Преобразовывают файл с разделением табуляцией для использования новых строк. В этом случае, изменение > к новым строкам:

sed 'y/>/\n/' file3 > outfile

y команда выполняет ту же функцию как tr, преобразование одного символа в другого, но можно использовать s управляйте здесь одинаково хорошо. С s, Вам нужно g воздействовать на каждое соответствие в строке (sed 's/>/\n/g').

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

$ sed '5~4s/^/>/' file | sed ':a;N;s/\n/ /;ba' | sed 'y/>/\n/'
Dog Cat Fish Lizard 
Wolf Lion Shark Gecko 
Coyote Puma Eel Iguana

Если конечные пробелы являются проблемой, можно добавить другую команду для удаления их:

| sed 's/ $//'
3
ответ дан 23 November 2019 в 03:49

Ради "полноты" вот чистое решение для удара:

#!/usr/bin/env bash

sep=$'\t'

while read one \
      && read two \
      && read three \
      && read four
do
  printf "%s\n" "$one$sep$two$sep$three$sep$four"
done

Работы также с пробелами, принимая IFS правильно установлен (который это должно по умолчанию, AFAIK). Кроме того, я думаю, что это могло даже быть портативным сценарием оболочки и работать с любым POSIX совместимая оболочка.

2
ответ дан 23 November 2019 в 03:49

Макрос энергии (зарегистрированный с q) мог применить Вашу операцию, затем пропустить три строки. Затем Вы просто выполняете тот макрос n времена.

например:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q
2
ответ дан 23 November 2019 в 03:49

Так как Вы попросили решение Gedit, что-то вроде этого должно работать:

Найдите:

(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+(\w+)[\r\n]+

Замена:

\1\t\2\t\3\t\4\n

Удостоверьтесь, что флажок для регулярных выражений отмечен.

Как это работает:

Первый шаг должен найти серию словесных символов, с \w +, и получить результаты в переменных \1 путем обертывания круглых скобок вокруг выражения:

(\w+)

Затем мы ищем серию конечных символов строки, \r и \n, или CR и LF. Так как Windows отформатировал использование файлов оба, мы создаем класс символов путем обертывания этих двух символов в квадратные скобки. Плюс заставляет его искать один или несколько символов:

[\r\n]+

Наконец, мы повторяем это еще 3 раза, храня каждое последующее слово в переменных \2, \3, и \4. Это делает нашу замену выражением простой. Мы просто должны поместить символы табуляции, \t, и символ новой строки, \n, в соответствующих местах для форматирования Вас нуждаются.

2
ответ дан 23 November 2019 в 03:49

Другие вопросы по тегам:

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