В Unix есть эти замечательные маленькие инструменты, которые называются вырезать
и вставить
. Инструмент вырезать
будет извлекать набор столбцов из своего ввода, а инструмент вставить
вставляет столбцы. Мы будем их использовать.
Я не собираюсь слишком заботиться о вашем конвейере (прямо сейчас, но посмотрите конец этого ответа), меня просто беспокоит проблема переключения столбцов.
Допустим, у меня есть эти данные в файле с именем cols.txt
:
$ cat cols.txt
1 a
2 b
3 c
$ paste -d ' ' cols.txt cols.txt
1 a 1 a
2 b 2 b
3 c 3 c
Утилита paste
обычно вставляет табуляцию между столбцами, но здесь мы сказали ей вставить вместо него пробел ( -d ''
).
Затем нужно просто извлечь второй и третий столбцы из вывода paste
с помощью cut
:
$ paste -d ' ' cols.txt cols.txt | cut -d ' ' -f 2,3
a 1
b 2
c 3
Мы сказали cut
что у нас есть пробелы в качестве «разделителей полей» ( -d ''
, иначе ожидаются табуляции) и что мы хотели бы иметь поля 2 и 3 ( -f 2,3
) , пожалуйста. (К сожалению, простой запрос cut
для столбцов « 2,1
» в исходном вводе не не поменяет местами столбцы.)
Итак, в конце концов, есть здесь действительно нет необходимости в беспорядочной магии регулярных выражений.
Вернемся к вашему конвейеру. Давайте отбросим это.Кажется, что вы хотите вставить номер строки в каждую строку. Для этого есть еще один инструмент Unix, который называется nl
("числовые строки"):
$ nl abc.txt
1 a
2 b
3 c
По умолчанию у вас есть номера строк для каждой непустой строки, которым предшествуют некоторые пробелы для заполнения и отделяются от исходной строки символом символ табуляции. Хотите ли вы также пронумеровать пустые строки, используйте
$ nl -b a abc.txt
Насколько я знаю, вы не можете заставить nl
поместить номера строк справа от строки, но это не проблема, потому что мы есть решение, которое меняет местами два столбца ввода:
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a 1
b 2
c 3
Мы отказались от указания здесь разделителей. nl
вставит пробелы, за которыми следует номер строки и табуляция в начале каждой строки. paste
вставляет вкладку между столбцами, а cut
разрезает вкладки, так что это будет работать.
Если вы хотите, чтобы между столбцами был один пробел (теперь есть табуляция и несколько пробелов), добавьте | tr -s '\ t' ''
команде. Это изменит («транслитерирует») все табуляции на пробелы и «сожмет» ( -s
) полученные последовательные пробелы в один пробел.
Если вы хотите вместо этого использовать запятую и пробел, используйте | tr '\ t' ','
вместо:
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3 | tr -s '\t ' ', '
a, 1
b, 2
c, 3
Это работает с файлом с несколькими словами в каждой строке, но не работает с файлами, содержащими символы табуляции:
$ cat abc.txt # no tabs in this file though
a text there is a
b goes hole in my
c here pants
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a text there is a 1
b goes hole in my 2
c here pants 3