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

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

6 Solutions collect form web for “Как использовать команду оболочки, чтобы показывать только первый столбец и последний столбец в текстовом файле?”

Почти готово. Просто поставьте обе колонки вместе друг с другом.

 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 

Просто замените с первого на последний | с | (или пространство, если вы предпочитаете):

 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)).

Вы все равно используете awk :

 awk '{ print $1, $NF }' file 

Если вы обнаружите, что awk- и sed-less, вы можете добиться того же самого с помощью coreutils:

 paste <( cut -d'|' -f1 file) \ <(rev file | cut -d'|' -f1 | rev) 

Кажется, вы пытаетесь получить первое и последнее поля текста, которые ограничены | ,

Я предположил, что ваш файл журнала содержит текст, как показано ниже,

 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 

Вероятно, вы должны сделать это с помощью sed – я бы все равно, но, просто потому, что никто еще не написал это:

 while IFS=\| read col1 cols do printf %10s%-s\\n "$col1 |" " ${cols##*|}" done <<\INPUT foo|dog|cat|mouse|lion|ox|tiger|bar INPUT 

ВЫВОД

  foo | bar 
  • Sudo выполнить сценарий оболочки по-разному по сравнению с прямым пользователем выполнить его
  • Почему «sudo su» в сценарии оболочки не запускает остальную часть скрипта как root?
  • Скрипт выполняется иначе, если выполняется из udev
  • В чем разница между «du -sh *» и «du -sh ./*»?
  • открытый скрипт оболочки
  • Имена файлов каталогов с sed с пробелами
  • Удалите 50GB самых старых файлов в busybox, когда используемая емкость достигает 95%
  • Итерация по наборам аргументов команды в Bash
  • Проблема с пробелами при использовании в команде find
  • Что означает «//» взамен от `which`
  • Что означает `: -` в сценарии оболочки
  • Linux и Unix - лучшая ОС в мире.