Команда для получения n-й строки STDOUT - PullRequest
180 голосов
/ 16 сентября 2009

Есть ли какая-нибудь команда bash, которая позволит вам получить n-ю строку STDOUT?

То есть что-то, что могло бы принять это

$ ls -l
-rw-r--r--@ 1 root  wheel my.txt
-rw-r--r--@ 1 root  wheel files.txt
-rw-r--r--@ 1 root  wheel here.txt

и сделайте что-то вроде

$ ls -l | magic-command 2
-rw-r--r--@ 1 root  wheel files.txt

Я понимаю, что это будет плохой практикой, когда пишу сценарии, предназначенные для повторного использования, НО при работе с оболочкой изо дня в день мне было бы полезно иметь возможность фильтровать свой STDOUT таким способом.

Я также понимаю, что это была бы полувысокая команда для записи (буфер STDOUT, возвращает определенную строку), но я хочу знать, есть ли какая-нибудь стандартная команда оболочки, чтобы сделать это, которая будет доступна без я бросаю сценарий на место.

Ответы [ 13 ]

295 голосов
/ 16 сентября 2009

Использование sed, просто для разнообразия:

ls -l | sed -n 2p

Использование этой альтернативы, которая выглядит более эффективной, поскольку она прекращает чтение ввода при печати требуемой строки, может генерировать SIGPIPE в процессе подачи, что, в свою очередь, может генерировать нежелательное сообщение об ошибке:

ls -l | sed -n -e '2{p;q}'

Я видел это достаточно часто, так что я обычно использую первый (который, во всяком случае, легче набирать), хотя ls - это не команда, которая жалуется, когда получает SIGPIPE.

Для диапазона строк:

ls -l | sed -n 2,4p

Для нескольких диапазонов линий:

ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
76 голосов
/ 16 сентября 2009
ls -l | head -2 | tail -1
39 голосов
/ 16 сентября 2009

Альтернатива хорошему способу головы / хвоста:

ls -al | awk 'NR==2'

или

ls -al | sed -n '2p'
21 голосов
/ 24 сентября 2009

С sed1line :

# print line number 52
sed -n '52p'                 # method 1
sed '52!d'                   # method 2
sed '52q;d'                  # method 3, efficient on large files

С awk1line :

# print line number 52
awk 'NR==52'
awk 'NR==52 {print;exit}'          # more efficient on large files
8 голосов
/ 16 сентября 2009

Ради полноты; -)

более короткий код

find / | awk NR==3

короче жизнь

find / | awk 'NR==3 {print $0; exit}'
6 голосов
/ 16 сентября 2009

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

ls -l | awk 'NR==2'

Обновление

Приведенный выше код не получит то, что мы хотим, из-за ошибки off-by-one: первая строка команды ls -l - это строка total . Для этого будет работать следующий пересмотренный код:

ls -l | awk 'NR==3'
6 голосов
/ 16 сентября 2009

Попробуйте это sed версия:

ls -l | sed '2 ! d'

Там написано "удалить все строки, которые не являются вторыми".

4 голосов
/ 16 сентября 2009

Вам легко доступен Perl?

$ perl -n -e 'if ($. == 7) { print; exit(0); }'

Очевидно, замените любое число на 7.

2 голосов
/ 14 июня 2014

Предложен еще один плакат

ls -l | head -2 | tail -1

но если вы направите трубку в хвост, похоже, что все до строки N обрабатывается дважды.

Обвивающий хвост в голову

ls -l | tail -n +2 | head -n1

будет эффективнее?

0 голосов
/ 31 марта 2016

Я добавил это в свой .bash_profile

function gdf(){
  DELETE_FILE_PATH=$(git log --diff-filter=D --summary | grep delete | grep $1 | awk '{print $4}')
  SHA=$(git log --all -- $DELETE_FILE_PATH | grep commit | head -n 1 | awk '{print $2}')
  git show $SHA -- $DELETE_FILE_PATH
}

И это работает

gdf <file name>
...