Команда для получения n-й строки STDOUT

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

То есть, что-то, что займет это

$ ls -l
[email protected] 1 root  wheel my.txt
[email protected] 1 root  wheel files.txt
[email protected] 1 root  wheel here.txt

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

$ ls -l | magic-command 2
[email protected] 1 root  wheel files.txt

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

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

Ответ 1

Используя 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'

Ответ 2

ls -l | head -2 | tail -1

Ответ 3

Альтернатива хорошему виду/хвосту:

ls -al | awk 'NR==2'

или

ls -al | sed -n '2p'

Ответ 4

От 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

Ответ 5

Для полноты; -)

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

find / | awk NR==3

более короткая жизнь

find / | awk 'NR==3 {print $0; exit}'

Ответ 6

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

ls -l | sed '2 ! d'

В нем говорится: "Удалите все строки, которые не являются вторыми".

Ответ 7

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

ls -l | awk 'NR==2'

Update

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

ls -l | awk 'NR==3'

Ответ 8

Доступен ли Perl для вас?

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

Очевидно, замените любой номер, который вы хотите для 7.

Ответ 9

Другой плакат предложил

ls -l | head -2 | tail -1

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

Трубопровод хвоста в голову

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

будет более эффективным?

Ответ 10

Да, самый эффективный способ (как уже указывал Джонатан Леффлер) - использовать sed с печатью и выйти:

set -o pipefail                        # cf. help set
time -p ls -l | sed -n -e '2{p;q;}'    # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}"            # cf. man bash | less -p 'PIPESTATUS'

Ответ 11

Хм

sed не работал в моем случае. Я предлагаю:

для "нечетных" строк 1,3,5,7... ls | awk '0 == (NR + 1)% 2'

для "четных" строк 2,4,6,8 ls | awk '0 == (NR)% 2'

Ответ 12

Для большей полноты.

ls -l | (for ((x=0;x<2;x++)) ; do read ; done ; head -n1)

Выбросьте строки, пока не дойдете до второго, затем распечатайте первую строку после этого. Таким образом, он печатает третью строку.

Если это только вторая строка.

ls -l | (read; head -n1)

Поместите столько "прочитанных как необходимо".

Ответ 13

Я добавил это в свой .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>