
Мне нужна помощь, чтобы разобраться, как использовать команду sed, чтобы показать только первый и последний столбцы в текстовом файле. Вот что у меня есть для столбца 1:
cat logfile | sed 's/\|/ /'|awk '{print $1}'
Моя слабая попытка отобразить и последний столбец была следующей:
cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'
Однако это берет первый столбец и последний столбец и объединяет их в один список. Есть ли способ четко вывести первый столбец и последний столбец с помощью команд sed и awk?
Пример ввода:
foo|dog|cat|mouse|lion|ox|tiger|bar
решение1
Почти готово. Просто поместите обе ссылки на столбцы рядом друг с другом.
cat logfile | sed 's/|/ /' | awk '{print $1, $8}'
Также обратите внимание, что вам здесь не нужно cat
.
sed 's/|/ /' logfile | awk '{print $1, $8}'
Также обратите внимание awk
, что разделителями столбцов являются |
символы , а не пробелы, так что вам sed
они не нужны.
awk -F '|' '{print $1, $8}' logfile
СогласнопредложениякКалеб, если вам нужно решение, которое по-прежнему выводит последнее поле, даже если их не ровно восемь, вы можете использовать $NF
.
awk -F '|' '{print $1, $NF}' logfile
Также, если вы хотите, чтобы вывод сохранил |
разделители, вместо использования пробела вы можете указать разделители полей вывода. К сожалению, это немного более неуклюже, чем просто использовать флаг -F
, но вот три подхода.
Разделители полей ввода и вывода можно назначить
awk
в самом блоке BEGIN.awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
Вы можете назначить эти переменные при вызове
awk
из командной строки с помощью-v
флага.awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
или просто:
awk -F '|' '{print $1 "|" $8}' logfile
решение2
В любом случае вы используете awk
:
awk '{ print $1, $NF }' file
решение3
Просто замените все от первого до последнего |
на |
(или пробел, если вам так удобнее):
sed 's/|.*|/|/'
Обратите внимание, что хотя нет никакой sed
реализации, где |
это является чем-то особенным (при условии, чторасширенныйрегулярные выражения не включены через -E
или -r
в некоторых реализациях), \|
сам по себе является особенным в некоторых, как GNU sed
. Так что вы должнынетпобег, |
если вы хотите, чтобы он соответствовал |
персонажу.
Если заменить на пробел и если ввод может уже содержать строки только с одним |
, то вам придется отнестись к этому по-особенному, так как это |.*|
не будет соответствовать им. Это может быть:
sed 's/|\(.*|\)\{0,1\}/ /'
(то есть сделать эту .*|
часть необязательной) Или:
sed 's/|.*|/ /;s/|/ /'
или:
sed 's/\([^|]*\).*|/\1 /'
Если вам нужны первое и восьмое поля независимо от количества полей во входных данных, то это просто:
cut -d'|' -f1,8
(все они будут работать с любой совместимой с POSIX утилитой, предполагая, что входные данные представляют собой допустимый текст (в частности, они, sed
как правило, не будут работать, если входные данные содержат байты или последовательности байтов, которые не образуют допустимые символы в текущей локали, например, printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'
в локали UTF-8)).
решение4
Похоже, вы пытаетесь получить первое и последнее поля текста, которые разделены символом |
.
Я предположил, что ваш файл журнала содержит текст, подобный приведенному ниже:
foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo
И вы хотите получить на выходе что-то вроде:
foo bar
bar foo
Если да, то вот команда для вашего
Через GNU sed,
sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file
Пример:
$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar