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

Юникод может использоваться непосредственно в директиве xmodmap keycode:

xmodmap -e "keycode 77 = U2327 Num_Lock"
11
задан 25 April 2018 в 15:49

24 ответа

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

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

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

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

См. например Sed One-Liners Explained:

Append строка к следующей, если она заканчивается обратным слэшем «\».
sed -e :a -e '/\\$/N; s/\\\n//; ta'

Однако IMHO было бы проще с одной из других стандартных утилит обработки текста, например

paste - - - - < file > file.tsv

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

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

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

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

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

или

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

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

16
ответ дан 22 May 2018 в 11:15
  • 1
    Замечание о концах строк в стиле Windows: стандартными инструментами для преобразования между ними и Unix-стилем являются dos2unix и unix2dos. – David Foerster 26 April 2018 в 13:50

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

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

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

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

См. например Sed One-Liners Explained:

Append строка к следующей, если она заканчивается обратным слэшем «\». sed -e :a -e '/\\$/N; s/\\\n//; ta'

Однако IMHO было бы проще с одной из других стандартных утилит обработки текста, например

paste - - - - < file > file.tsv

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

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

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

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

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

или

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

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

16
ответ дан 17 July 2018 в 16:11

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

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

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

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

См. например Sed One-Liners Explained:

Append строка к следующей, если она заканчивается обратным слэшем «\». sed -e :a -e '/\\$/N; s/\\\n//; ta'

Однако IMHO было бы проще с одной из других стандартных утилит обработки текста, например

paste - - - - < file > file.tsv

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

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

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

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

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

или

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

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

16
ответ дан 23 July 2018 в 17:05

Вы можете использовать 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'

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

Dog Cat Fish    Lizard
Wolf    Lion    Shark   Gecko
Coyote  Puma    Eel Iguana
13
ответ дан 22 May 2018 в 11:15
  • 1
    Этот метод имеет то преимущество, что он ведет себя разумно, даже если общее количество строк ввода не кратно четырем. – Eliah Kagan 25 April 2018 в 19:16

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

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

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

ORS: Сепаратор записи вывода (по умолчанию = новая строка). Он добавляется в конце каждой команды печати. NR: номер текущей строки awk обрабатывается.

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

3
ответ дан 22 May 2018 в 11:15

Еще один самый короткий awk подход:

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

Этот printf единственный столбец, за которым следуют следующий и следующий и ... и символ Tab \t после каждого, но будет printf a ewline, когда Number of Record был фактором 4 (где NR%4 вернет 0 (false), что делает трёхмерный оператор condition(s)?when-true:when-false).

3
ответ дан 22 May 2018 в 11:15

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

Добавление символа в любую другую текстовую строку

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

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

Затем вам нужно удалить новые строки, которые могут быть выполнены с помощью цикла 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 оставляет конечный newline, в то время как версия 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
ответ дан 22 May 2018 в 11:15

Для «полноты» здесь используется чистое решение bash:

#!/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
ответ дан 22 May 2018 в 11:15
  • 1
    Это не переносимо для совместимых с POSIX оболочек вообще, потому что формация $' ' цитирования не требуется POSIX. Например, в dash (который предоставляет sh по умолчанию для Ubuntu), запуск printf '%s\n' $'a\tb' только выдает $a\tb. Это не значит, что это не полезно; он работает в bash. Однако, как и в случае с некоторыми другими решениями, опубликованными пользователями, он производит неполный вывод, если количество строк ввода не кратно четырем. Кроме того, я рекомендую использовать read -r, так как нет оснований полагать, что здесь требуется расширение обратных косов в входном файле. – Eliah Kagan 25 April 2018 в 21:14
  • 2
    Вы можете просто сделать printf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$four" – terdon♦ 26 April 2018 в 11:59

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

например:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q
2
ответ дан 22 May 2018 в 11:15

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

Найти:

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

Заменить на:

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

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

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

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

(\w+)

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

[\r\n]+

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

2
ответ дан 22 May 2018 в 11:15

Вы можете использовать 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'

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

Dog Cat Fish Lizard Wolf Lion Shark Gecko Coyote Puma Eel Iguana
13
ответ дан 17 July 2018 в 16:11

Для «полноты» здесь используется чистое решение bash:

#!/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
ответ дан 17 July 2018 в 16:11

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

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

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

ORS: Сепаратор записи вывода (по умолчанию = новая строка). Он добавляется в конце каждой команды печати. NR: номер текущей строки awk обрабатывается.

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

3
ответ дан 17 July 2018 в 16:11

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

Найти:

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

Заменить на:

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

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

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

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

(\w+)

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

[\r\n]+

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

2
ответ дан 17 July 2018 в 16:11

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

например:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q
2
ответ дан 17 July 2018 в 16:11

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

Добавление символа в любую другую текстовую строку

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

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

Затем вам нужно удалить новые строки, которые могут быть выполнены с помощью цикла 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 оставляет конечный newline, в то время как версия 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
ответ дан 17 July 2018 в 16:11

Еще один самый короткий awk подход:

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

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

3
ответ дан 17 July 2018 в 16:11

Вы можете использовать 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'

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

Dog Cat Fish Lizard Wolf Lion Shark Gecko Coyote Puma Eel Iguana
13
ответ дан 23 July 2018 в 17:05
  • 1
    Этот метод имеет то преимущество, что он ведет себя разумно, даже если общее количество строк ввода не кратно четырем. – Eliah Kagan 25 April 2018 в 19:16

Для «полноты» здесь используется чистое решение bash:

#!/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 July 2018 в 17:05
  • 1
    Это не переносимо для совместимых с POSIX оболочек вообще, потому что формация $' ' цитирования не требуется POSIX. Например, в dash (который предоставляет sh по умолчанию для Ubuntu), запуск printf '%s\n' $'a\tb' только выдает $a\tb. Это не значит, что это не полезно; он работает в bash. Однако, как и в случае с некоторыми другими решениями, опубликованными пользователями, он производит неполный вывод, если количество строк ввода не кратно четырем. Кроме того, я рекомендую использовать read -r, так как нет оснований полагать, что здесь требуется расширение обратных косов в входном файле. – Eliah Kagan 25 April 2018 в 21:14
  • 2
    Вы можете просто сделать printf '%s\t%s\t%s\t%s\n' "$one" "$two" "$three" "$four" – terdon♦ 26 April 2018 в 11:59

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

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

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

ORS: Сепаратор записи вывода (по умолчанию = новая строка). Он добавляется в конце каждой команды печати. NR: номер текущей строки awk обрабатывается.

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

3
ответ дан 23 July 2018 в 17:05

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

Найти:

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

Заменить на:

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

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

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

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

(\w+)

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

[\r\n]+

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

2
ответ дан 23 July 2018 в 17:05

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

например:

qq $ J i <TAB> <ESC> $ J i <TAB> <ESC> $ J i <TAB> <ESC> ^^ j qq 100 @q
2
ответ дан 23 July 2018 в 17:05

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

Добавление символа в любую другую текстовую строку

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

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

Затем вам нужно удалить новые строки, которые могут быть выполнены с помощью цикла 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 оставляет конечный newline, в то время как версия 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 July 2018 в 17:05

Еще один самый короткий awk подход:

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

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

3
ответ дан 23 July 2018 в 17:05

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

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