Команда для получения 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>