Вопрос:
Как получить одну строку из файла?
file.txt «aaaaaaa» «bbbbbbb» «ccccccc» «ddddddd»
Мне нужно получить строку 3 ( “ccccccc” )
Спасибо.
Лучший ответ:
Если вы знаете, что вам нужна строка 3, один подход заключается в использовании head для получения первых трех строк и tail для получения только последней из них:
varname=»$(head -n 3 file.txt | tail -n 1)»
Другой подход, используя только Bash builtins, состоит в том, чтобы вызвать read три раза:
{ read ; read ; IFS= read -r varname } < file.txt Ответ №1
sed – ваш друг. sed -n 3p печатает третью строку (-n: нет автоматической печати, 3p: печатать, когда номер строки – 3). Вы также можете иметь гораздо более сложные шаблоны, например sed -n 3,10p для печати строк с 3 по 10.
Если файл очень большой, вы можете подумать о том, чтобы не перебирать весь файл, а после печати. sed -n ‘3{p;q}’
Ответ №2
Здесь можно сделать это с помощью awk:
awk ‘FNR==3 {print; exit}’ file.txt
Объяснение:
- awk ‘…’: вызывать awk, инструмент для управления файлами по очереди. Инструкции, заключенные одинарными кавычками, выполняются awk.
- FNR==3 {print; exit}: FNR означает “Записи номеров файлов”; просто подумайте об этом как о “количестве строк, прочитанных до сих пор для этого файла”. Здесь мы говорим, что если мы находимся на третьей строке файла, напечатаем всю строку, а затем немедленно выйдем из awk, чтобы не тратить время на чтение остального большого файла.
- file.txt: укажите входной файл в качестве аргумента awk для сохранения cat.
Ответ №3
Есть много возможностей: Попробуйте:
sed ‘3!d’ test
Вот очень быстрая версия:
sed «1d; 2d; 3q» Ответ №4
Разрешены ли другие инструменты, кроме bash? В системах, которые включают bash, вы обычно найдете sed и awk или другие базовые инструменты:
$ line=»$(sed -ne 3p input.txt)» $ echo «$line»
или
$ read line < <(awk ‘NR==3’ input.txt) $ echo «$line»
или если вы хотите оптимизировать это, убрав после чтения третьей строки:
$ read line < <(awk ‘NR==3{print;nextfile}’ input.txt) $ echo «$line»
или как насчет еще более простых инструментов (хотя и менее оптимизированных):
$ line=»`head -n 3 input.txt | tail -n 1`» $ echo «$line»
Конечно, если вы действительно хотите сделать это все в bash, вы все равно можете сделать его одним лайнером, не используя никаких внешних инструментов.
$ for (( i=3 ; i— ; )); do read line; done < input.txt $ echo «$line»
Существует много способов добиться того же. Выберите тот, который имеет смысл для вашей задачи. В следующий раз, возможно, объясните свои общие потребности немного лучше, чтобы мы могли дать вам ответы, более применимые к вашей ситуации.
Ответ №5
Так как, как обычно, все остальные ответы включают тривиальные и обычные вещи (труба через grep, затем awk, затем sed, затем cut или you-name-it), здесь очень необычное и (к сожалению) очень известный (так, я утверждаю, что у меня самый оригинальный ответ):
mapfile -s2 -n3 -t < input.txt echo «$MAPFILE»
Я бы сказал, что это довольно эффективно (mapfile достаточно эффективен и он встроен bash).
Готово!
Ответ №6
Быстрая версия bash;
while (( ${i:-1} <= 3 )); do (( $i == 3 )) && read -r line; (( i++ )) done < file.txt
Выход
echo «$line» # Third line «ccccccc»
Объяснение
- while (( ${i:-1} <= 3 )) – считать до $i равно 3, а затем выйти из цикла.
- (( $i == 3 )) – Если $i равно 3 выполнить строку чтения.
- read -r line – Прочитайте строку файла в переменной $line.
- (( i++ )) – Приращение $i на 1 в каждом цикле.
- done < file.txt – файл трубы в цикл while.