Самый быстрый способ считать последнюю строку в шаблоне нескольких файлов с тем же расширением

В той командной строке Ваша оболочка открывается /etc/portage/make.conf в добавляют режим, делает это stdout нового процесса и выполнений sudo в том новом процессе. Это не sudo ни echo это открывает файл, именно Ваша оболочка работает с Вашими учетными данными.

Вам был бы нужен файл, который будет открыт командой, запущенной как корень. Таким образом, это могло быть:

sudo sh -c 'echo "abc-abc/abc/abc" >> /etc/portage/make.conf'

Или:

echo "abc-abc/abc/abc" | sudo tee -a /etc/portage/make.conf > /dev/null
3
11.01.2015, 13:50
4 ответа

с помощью найти + grep:

find . -name '*.txt' -exec sh -c 'grep -HPo "frames=\K.*" "$0" | tail -n1' {} \;

и с помощью оболочки для цикла + grep аналогичным образом:

for file in *.txt; do grep -HPo 'frames=\K.*' "$file" | tail -n1; done
2
27.01.2020, 21:12

С pax (вероятно также большинство любых tar) и tr и GNU sed:

pax -w ./*txt | 
tr -s \\0     | 
sed -nz '/txt$/h
         /\n*.*frames\(=[0-9]*\).*\n/!d
    H;x;s//\1/p'
1
27.01.2020, 21:12

Используя gawk и при условии, что на линии будет только одна =, вы можете сделать:

gawk -F= 'ENDFILE { print FILENAME"="$2 }' *.txt

Update

Просто поняв, что я неправильно понял этот вопрос, я подумал, что строка, которую вы ищете, всегда будет последней строкой. Чтобы использовать последнюю строку, которая начинается с кадров=, для gawk do:

gawk -F= '/^frames=/ { frames=$2 } ENDFILE { print FILENAME"="frames }' *.txt

Или с любой awk:

for file in *.txt; do
  awk -F= '/^frames=/ { frames=$2 } END { print FILENAME"="frames }' "$file"
done
2
27.01.2020, 21:12

Вы можете сделать это с awk

awk -F= '/^frame/{line=FILENAME "=" $2}NR!=1 && FNR==1{print line}END{print line}' *.txt

или с SED (версия GNU более 4.2.2)

sed -sn '/^frame/{s///;h};${F;x;p}' *.txt | sed 'N;s/\n//'
2
27.01.2020, 21:12

Теги

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