Как посмотреть 17-ю (или последнюю, если меньше) строку в файлах папки?

Я полагаю, что вы столкнулись с проблемой, описанной здесь :https://github.com/MycroftAI/mycroft-core/issues/705

Мы включили исправление в этот PR :https://github.com/MycroftAI/mycroft-core/pull/751По сути, это обновляет версию pyOpenSSL в файле requirements.txt. Это исправление находится в ветке «dev» ядра mycroft -прямо сейчас и будет перемещено в master с выпуском 0.8.13

.

После этого изменения вам, вероятно, придется удалить папку ~/.virtualenv, а затем повторно запустить dev _setup.sh

8
21.08.2019, 17:36
3 ответа

другой подход с помощью find,exec и sed

watch find. -type f -name \"*\" -exec sh -c \'\( printf '%-50s ' {} \; sed -n 17p {}\)\' \\\;
0
27.01.2020, 20:08

Объедините headи tail, как в этих двух примерах:

$ seq 1 80 | head -n 17 | tail -n 1
17

$ seq 1 10 | head -n 17 | tail -n 1
10

Итак, чтобы решить вашу актуальную проблему, введите команду:

watch 'for f in *; do head -n 17 -- "$f" 2>/dev/null | tail -n 1 ; done'

Обратите внимание на часть 2>/dev/null, она необходима, потому что *будет соответствовать каталогам и любым файлам, на чтение которых у вас может не быть разрешения, что приведет к появлению сообщения об ошибке, которое вы, вероятно, захотите скрыть.

11
27.01.2020, 20:08

С помощью GNUawk:

watch -x gawk '
  FNR == 17 {nextfile}
  ENDFILE   {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'./*

Что дает вывод, подобный:

       ./file1[17] line17
 ./short-file2[05] line 5 is the last

Обратите внимание, что глобус ./*расширяется только один раз во время вызова watch.

Ваша watch head -n 17 *была уязвимостью, связанной с внедрением произвольной команды, поскольку расширение этого *было фактически интерпретировано как код оболочки оболочкой, которая вызывает watchдля интерпретации объединения своих аргументов с пробелами.

Если в текущем каталоге есть файл с именем $(reboot), он перезагрузится.

С помощью -xмы говорим watchпропустить оболочку и выполнить команду напрямую. В качестве альтернативы вы можете сделать:

watch 'exec gawk '\''
  FNR == 17 {nextfile}
  ENDFILE   {if (FNR) printf "%15s[%02d] %s\n", FILENAME, FNR, $0}'\''./*'

Для watchзапуска оболочки, которая будет расширять этот ./*глобус на каждой итерации. watch foo barпо сути то же самое, что и watch -x sh -c 'foo bar'. При использовании watch -xвы можете указать, какую оболочку вы хотите, и, например, выбрать более мощную, такую ​​​​как zsh, которая может выполнять рекурсивную подстановку и ограничивать обычные файлы :

.
watch -x zsh -c 'awk '\''...'\''./**/*(.)'

Без gawkвы все равно могли бы сделать что-то вроде:

watch '
  for file in./*; do
    [ -s "$file" ] || continue
    printf "%s: " "$file"
    head -n 17 < "$file" | tail -n 1
  done'

Вывод вида:

./file1: line17
./short-file2: line 5 is the last

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

15
27.01.2020, 20:08

Теги

Похожие вопросы