Есть ли какая-либо команда 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, возврат определенной строки), но я хочу знать, есть ли там какая-то команда стандартная команда, которая будет доступна без того, чтобы я сбросил script на место.
Используя 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'
ls -l | head -2 | tail -1
head -n 2 | tail -n 1
- современные головы и хвосты имеют тенденцию выдавать предупреждения иначе.
head -n M | tail -n M-N+1
), а обобщение для обработки нескольких диапазонов невозможно.
Альтернатива хорошему виду/хвосту:
ls -al | awk 'NR==2'
или
ls -al | sed -n '2p'
От 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
exit
отличный трюк для больших файлов
Для полноты; -)
более короткий код
find / | awk NR==3
более короткая жизнь
find / | awk 'NR==3 {print $0; exit}'
ls
- первоначальный вопрос был о чьём-то STDOUT
, поэтому я подумал, что лучше иметь его побольше.
Попробуйте эту версию sed
:
ls -l | sed '2 ! d'
В нем говорится: "Удалите все строки, которые не являются вторыми".
Вы можете использовать awk:
ls -l | awk 'NR==2'
Вышеприведенный код не получит того, чего мы хотим, из-за ошибки "один за другим": первая строка ls -l - это общая строка. Для этого будет работать следующий пересмотренный код:
ls -l | awk 'NR==3'
Доступен ли Perl для вас?
$ perl -n -e 'if ($. == 7) { print; exit(0); }'
Очевидно, замените любой номер, который вы хотите для 7.
$ awk 'NR % 7' filename
чтобы напечатать каждую седьмую строку в файле.
Другой плакат предложил
ls -l | head -2 | tail -1
но если вы заводите голову в хвост, все выглядит так, как будто все линии линии N обрабатываются дважды.
Трубопровод хвоста в голову
ls -l | tail -n +2 | head -n1
будет более эффективным?
Хм
sed не работал в моем случае. Я предлагаю:
для "нечетных" строк 1,3,5,7... ls | awk '0 == (NR + 1)% 2'
для "четных" строк 2,4,6,8 ls | awk '0 == (NR)% 2'
Да, самый эффективный способ (как уже указывал Джонатан Леффлер) - использовать 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'
Для большей полноты.
ls -l | (for ((x=0;x<2;x++)) ; do read ; done ; head -n1)
Выбросьте строки, пока не дойдете до второго, затем распечатайте первую строку после этого. Таким образом, он печатает третью строку.
Если это только вторая строка.
ls -l | (read; head -n1)
Поместите столько "прочитанных как необходимо".
Я добавил это в свой .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>
p
- это операторsed
который печатает строки, идентифицируемые диапазоном предшествующих ему строк. Таким образом,2,4p
означает печать строк 2, 3, 4.