Как использовать команду оболочки, чтобы отобразить только первый и последний столбцы в текстовом файле?

Как использовать команду оболочки, чтобы отобразить только первый и последний столбцы в текстовом файле?

Мне нужна помощь, чтобы разобраться, как использовать команду 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

Связанный контент