Громоздким решением было бы запустить несколько экземпляров следующей команды в фоновом режиме:
avahi-publish -a -R whatever.local 192.168.123.1
Лучшее решение, вероятно, - публикация cnames с использованием python-avahi. См., Например, https://github.com/airtonix/avahi-aliases или http://www.avahi.org/wiki/Examples/PythonPublishAlias
Обновление:
{{1} } Похоже, что авахи вики больше нет. Вот заархивированная страница ссылки, которую я разместил: https://web.archive.org/web/20151016190620/http://www.avahi.org:80/wiki/Examples/PythonPublishAlias
Вот вариант, если у вас GNU awk, который полностью избегает циклов оболочки:
xargs -d '\n' -a locationfile.txt gawk 'BEGINFILE{print FILENAME} 1' > newfile
или с GNU sed:
xargs -d '\n' -a locationfile.txt sed -s '1F' > newfile
Если вам все равно о точном формате имен файлов, то вы можете использовать этот трюк с head
:
xargs -d '\n' -a locationfile.txt head -vn -0 > newfile
( -n -0
сообщает head
выводить все строки кроме первого 0 т.е. всех строк).
Перед cat
выполните echo
или printf
имени файла:
while read line; do printf '%s\n' "$line"; cat "$line"; done <locationfile.txt >finalfile
Или, более читабельно:
while read line; do
printf '%s\n' "$line"
cat "$line"
done <locationfile.txt >finalfile
Обратите внимание, что для этого требуются все пути в locationfile.txt
, чтобы в них не было \
.
Хотя наличие \
в именах путей очень необычно, было бы безопаснее использовать
while read -r line; do
printf '%s\n' "$line"
cat "$line"
done <locationfile.txt >finalfile
... у которого нет таких же ограничений.
Добавление проверки, чтобы убедиться, что файл действительно существует, и вывод предупреждения, если это не так:
while read -r line; do
if [[ -f "$line" ]]; then
printf '%s\n' "$line"
cat "$line"
else
printf 'Warning: "%s" does not exist\n' "$line" >&2
fi
done <locationfile.txt >finalfile
«Не существует» здесь означает «по крайней мере, не является обычным файлом».
Если вы хотите, чтобы там же был ""
как своего рода маркер содержимого-конца файла, просто поместите его после cat
:
while read -r line; do
if [[ -f "$line" ]]; then
printf '%s\n' "$line"
cat "$line"
echo '""'
else
printf 'Warning: "%s" does not exist\n' "$line" >&2
fi
done <locationfile.txt >finalfile
И наконец, дайте вещам самодокументированные имена:
while read -r file_path; do
if [[ -f "$file_path" ]]; then
printf '%s\n' "$file_path"
cat "$file_path"
echo '""'
else
printf 'Warning: "%s" does not exist\n' "$file_path" >&2
fi
done <file_paths.txt >files_concat_with_paths.txt
while read file; do
( echo "$file"; cat "$file"; echo '"""' ) >> /path/to/outputfile
done < /path/to/filelist
Подход AWK через функцию system ()
. Мы составляем командную строку через sprintf
и передаем ее в system ()
$ awk '{print $0; cmd=sprintf("cat \"%s\"",$0);system(cmd); print "\"\""}' filenames.txt
/home/xieerqi/input1.txt
Hello, I am input file #1
And this is second line of the text
""
/home/xieerqi/input2.txt
And I am input file #2
Roses are red, violets are blue
AWK is awesome, Python is too
""
/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
""
и подход Perl, но с открытием файла в коде:
$ perl -ne 'chomp; open($fh,$_) or die;print "$_\n";while($line = <$fh>){ print $line; print "\"\"\n" if eof}' filenames>
/home/xieerqi/input1.txt
Hello, I am input file #1
And this is second line of the text
""
/home/xieerqi/input2.txt
And I am input file #2
Roses are red, violets are blue
AWK is awesome, Python is too
""
/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
""
Вы можете просто добавить echo "$ line"
в свой цикл:
cat locationfile.txt | while read line; do echo "$line" && cat "$line"; done
Другой подход Perl:
$ perl -le 'do{print $_,`cat $_`,"\"\"";} for <>' locationfile.txt
text
text
text
""
text
text
text
""
text
text
text
""
Здесь используется немного Магия Perl и, возможно, потребуется объяснение. -l
удаляет завершающие символы новой строки из каждой строки ввода и добавляет новую строку к каждому вызову print
. -e
- это то, как вы даете сценарий perl
.
Теперь <>
- это «содержимое входного файла, разделенное на массив». Итак, do {foo} for <>
будет запускать foo
в каждой строке входного файла. Внутри этого цикла for
для каждой входной строки назначается специальная переменная $ _
. Синтаксис `command`
запустит команду
в оболочке по умолчанию (системный вызов) и вернет ее результат. Итак, cat $ _
будет cat
каждое имя файла в locationfile.txt
.
В целом, print $ _, `cat $ _`," \ "\" "
напечатает имя файла (в настоящее время в $ _
), результат cat
(содержимое файла), а затем ""
(но нам нужно их избежать, поэтому \ "\"
).
Другими словами, этот сценарий означает «прочитать каждую строку ввода, распечатать ее, cat
файл, который она содержит, и вывести »
после каждого файла.