В зависимости от Вашего дистрибутива Linux и вида установки (минимальный, настольно-центральный, и т.д.) at
(и atd
в демоне планировщика заданий), установлен по умолчанию или нет.
Для проверки его, можно дать команды как:
$ which at
/usr/bin/at
$ which atd
/usr/bin/atd
$ yum whatprovides atd # to get the package name
$ yum info pkg-name # to see if it is installed
(принятие конфетки доступно на SuSe - использование системы Fedora здесь),
Если пакет не установлен, можно установить его через диспетчер пакетов, например, что-то как:
$ yum install at # on fedora at least
Если это установлено, возможно, демон не запускается на начальной загрузке по умолчанию.
Видеть если это выполнение:
$ pgrep -l atd
Или просто протестируйте его как это
$ echo echo hello world | at now
(смотрите, Ваша система входит в систему другой терминал, и/или проверьте свой локальный почтовый ящик),
Как запустить, это зависит от Вашей init-системы, если бы это является олдскульным, это было бы что-то как:
$ /etc/init.d/atd start
Если бы это - systemd, это было бы что-то как:
$ systemctl start atd
Поскольку init.d основывал систему также для systemd каждый, там также команды, чтобы отобразить состояние сервиса как фактическое время отправления и заставить его запуститься на начальной загрузке.
Но скорее всего atd
запускается по умолчанию после того, как установка и это являются установкой по умолчанию, чтобы быть запущенными при начальной загрузке системы.
Так что мне нравится SED
Ответ может быть
for file in file.log.*
do
echo "file: $file"
echo -n "first line: "
cat "$file" | sed -n '/^\s*$/!{p;q}'
echo -n "last line: "
tac "$file" | sed -n '/^\s*$/!{p;q}'
done
Попробуйте:
awk -F'\n' -vRS="" '
{
print "file: " FILENAME;
gsub(/\n[[:blank:]]+|[[:blank:]]+\n/,"");
print "first line: " $1;
print "last line: " $NF;
}
' file.log.*
Другим подходом было бы использование головы
и хвоста
:
EDIT (Спасибо за предложение @don_crissti! )
for file in file.log.*
do
echo "file: $file"
echo -n "first line: "
grep -v '^\s*$' "$file" | head -n1
echo -n "last line: "
grep -v '^\s*$' "$file" | tail -n1
done
Для полноты, вот SD-ответ, который один раз читает через каждый файл (надеюсь, быстрее, чем несколько SED
, CAT
и TAC
Завершение, если файлы большие):
for file in file.log.*; do
echo "file: $file"
sed -n "
/[^[:space:]]/ { # Match first non-whitespace line
h # Copy to hold buffer
s/^/first line: / p # Add prefix and print
:loop
$ { # Match last line
g # Get contents of hold buffer
s/^/last line: / p # Add prefix and print
}
n # Load next line
/[^[:space:]]/ h # Copy non-whitespace line to hold buffer
b loop # Jump back to process next line
}" "$file"
done
Что? Нет Perl?
for file in file.log.*; do
echo "FILE: $file";
perl -ne 'if(/\S/){$k++; $l=$_};
print "First line: $_" if $k==1;
END{print "Last line: $l\n"}' "$file";
done
для файла в file.log.*
: итерация по всем файлам, имена которых начинаются с file.log.
в текущем каталоге и сохранить каждый из них как $file
. echo "FILE: $file";
: распечатайте имя файла. perl -ne
: читаем текущий входной файл построчно (-n
), сохраняем каждую строку как специальную переменную Perl $_
, и запускаем на ней скрипт, заданный -e
. if(/\S/){$k++; $l=$_}
: если текущая строка соответствует небелому символу (\S
), сохраните строку как $l
и увеличьте счетчик $k
на единицу. выведите "First line: $_" if $k==1;
: выведите текущую строку ($_
) если $k
равно 1
. При этом будет выведена 1-я небелая строка. END{выведите "Последняя строка: $l\n"}
: это выполняется после того, как все входные строки будут прочитаны. Так как мы сохраняем каждую строку без пробелов как $l
, то в конце файла $l
будет последней строкой без пробелов. Таким образом, будет выведена последняя строка. Другой подход:
for file in file.log.*; do
printf "FILE: %s\nFirst line: %s\nLast line: %s\n\n" \
"$file" \
"$(grep -Em 1 '\S' "$file")" \
"$(tac "$file" | grep -Em1 '\S' )";
done
Это тот же самый цикл для
только здесь мы используем printf
для печати трех строк. Имя файла и вывод этих двух команд:
grep -Pm 1 '\S' "$file"
: В команде -E
активируются расширенные регулярные выражения, которые позволяют нам использовать \S
для "не-белых пространств". -m1
означает "выход после первого найденного совпадения". так "$file" | grep -Em1 '\S'
: так
обратная cat
. Он выведет содержимое файла, но из последней строки в первую. Таким образом, эта команда выведет последнюю не белую строку. команда awk:
awk -v OFS=: '
FNR==1 {
# the last non-blank line from the previous file
if (line) {print filename, fnr, line}
filename=FILENAME
line=""
p=0
}
/^[[:blank:]]*$/ {next}
!p {
# the first non-blank line
print FILENAME, FNR, $0; p=1
}
{fnr=FNR; line=$0}
END {print filename, fnr, line}
' *
для каждого файла, выведите имя файла, номер строки и строку, разделенные двоеточием.
GNU awk v4 имеет шаблоны BEGINFILE и ENDFILE, которые значительно упрощают дело:
gawk -v OFS=: '
BEGINFILE {p=0}
/^[[:blank:]]*$/ {next}
!p {print FILENAME, FNR, $0; p=1}
{fnr=FNR; line=$0}
ENDFILE {print FILENAME, fnr, line}
' *
strm_1st_last() ( unset l i c n
l=1 i='i\\\\' c='c\\\\' n='\
'; eval "echo |sed -n \":b
/[^[:blank:]]/h;$( wc -l "$@" |
sed -e '${1!d' -e "};s/[\"\/]/\\\\&/g
s/^[ 0]*\([^ 0-9]\)/1$i$n empty: \1/;/\n/b
s|^ *\([0-9]\{1,\}\) *\(.*\)|\\
\$((1+(l+=\\1)-\\1)){$i$n\\2$n :l\\
s/.*[^[:blank:]]/ \\&/p;//h;t\\
n;\$((l-1)){ //bb$n//!$c$n\ALL BLANK$n};bl$n}\\
\${l}{ x;s/^/ /p;s/.*//;x;d$n}|")"'" - "$@"'
)
Эта функция полагается на один процесс sed
для создания работоспособного сценария за секунду. Что ж, он не просто полагается на sub-shell sed
, но также и wc
, чтобы сначала получить общие номера строк для каждого из своих аргументов, и сама оболочка для подсчета арифметических выражений sed
строит как ссылки на строки для второго sed
.
Обычно он обрабатывает все аргументы как единый поток. Например, если вы это сделаете:
seq 10 > file1; seq 5 > file2; sed -n \$= file[12]
sed
напечатает ...
15
... потому что он автоматически объединяет все аргументы имени файла в единый поток данных. Так что мы просто работаем с этим.
Сначала wc
запрашивается отчет обо всех их длинах, а затем sed
переходит к работе, превращая его в работоспособный сценарий ввода на второй sed
].
Если wc
сообщает, что в каком-либо из файлов есть 0 строк, sed
напечатает пусто: имя файла для него и всех остальных прежде всего. (хотя, наверное, точнее было бы 0 строк).
Если при сканировании участка входных строк, который включает весь файл sed
, вообще нет непустых символов, sed
сообщит об этом ВСЕ ПУСТО (это единственный тип строкового отчета без отступа)
Для всех остальных случаев sed
печатает первую и последнюю непустые строки для каждого из своих аргументов и перед каждой парой с отступом имя файла без отступа. Это не обрабатывает имена файлов, содержащие символы новой строки - хотя, вероятно, для этого не потребуется намного больше.
Итак, если я сделаю ...
strm_1st_last file[12]
file1
1
10
file2
1
5
или ...
: >file2; strm_1st_last file[12]
empty: file2
file1
1
10
... или ...
strm_1st_last ~/*.sh
empty: /home/mikeserv/alleq.sh
empty: /home/mikeserv/mansed5.sh
/home/mikeserv/chrome.sh
#!/bin/bash
) &
/home/mikeserv/crap.sh
ALL BLANK
/home/mikeserv/getopts.sh
c=$# t=\ l='
done; printf '%s\n' "'${str#?}'"; done
/home/mikeserv/mansedmaybe.sh
mansed () {
);}
/home/mikeserv/mansed.sh
mansed () {
);}
/home/mikeserv/pr_after.sh
pr_after() if _i= _o=D OPTIND=1 _n='\
fi
/home/mikeserv/script.sh
#!/usr/bin/sh
echo done
/home/mikeserv/serial.sh
sq() ( IFS=\' set -f
# a b
/home/mikeserv/your_config.sh
zifs() { eval "shift ${3+3}
)
/home/mikeserv/ytplay.sh
ytplay() (
)
/home/mikeserv/zifs.sh
zifs() { eval "shift ${3+3}
)
Попробуйте следующее:
for file in $(ls) ; do cat $file | sed -n '1p;$p' ; done