Расположение выходного файла и его содержимое на основе списка файлов

Громоздким решением было бы запустить несколько экземпляров следующей команды в фоновом режиме:

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 ​​

5
19.01.2017, 01:48
6 ответов

Вот вариант, если у вас 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 т.е. всех строк).

3
27.01.2020, 20:31

Перед 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
8
27.01.2020, 20:31
while read file; do
    ( echo "$file"; cat "$file"; echo '"""' ) >> /path/to/outputfile
done < /path/to/filelist
3
27.01.2020, 20:31

Подход 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
""
2
27.01.2020, 20:31

Вы можете просто добавить echo "$ line" в свой цикл:

cat locationfile.txt | while read line; do echo "$line" && cat "$line"; done
2
27.01.2020, 20:31

Другой подход 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 файл, который она содержит, и вывести » после каждого файла.

{{ 1}}
3
27.01.2020, 20:31

Теги

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