Как я копирую содержание каждого файла в списке в другой файл?

У меня есть список имен файлов в названном файле list_of_files.txt.

Я хочу скопировать содержание каждого файла в том списке в другой названный файл all_compounds.sdf.

Как я должен сделать это из командной строки?

15
задан 3 January 2017 в 02:59

3 ответа

Не используйте простую подстановку команд для получения имен файлов (которые могут легко разрываться с пробелами и другими специальными символами). Используйте что-то вроде xargs:

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

или цикл while read:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

Чтобы безопасно использовать подстановку команд, по крайней мере установите IFS только на новую строку и отключите globbing (расширение по шаблону):

(set -f; IFS= 

Окружающие скобки () должны запускать это в подоболочке, чтобы эти изменения не повлияли на текущую оболочку.

\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

Окружающие скобки () должны запускать это в подоболочке, чтобы эти изменения не повлияли на текущую оболочку.

20
ответ дан 23 November 2019 в 02:41

Быстрый и грязный путь...

cat $(cat list_of_files.txt) >> all_compounds.sdf

Пожалуйста, примите во внимание: это только работает, если имена файлов в Вашем списке будут очень хорошо вестись себя - то вещи пойдут не так, как надо, если у них будут пробелы, новые строки или любые символы, которые имеют особое значение к оболочке - используют этот ответ вместо этого для надежных результатов),

Примечания

  • cat связывает файлы. Это также печатает их содержание.
  • Используя замену команды command2 $(command1) можно передать вывод command1 (cat list...) к command2 (cat) который связывает файлы.
  • Затем используйте перенаправление >> отправить вывод в файл вместо того, чтобы печатать к stdout. Если Вы хотите видеть вывод, использовать tee вместо этого:

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
    

(Я использовал >> вместо > и tee с -a переключитесь в случае, если Ваш файл уже существует - это добавляет в файл вместо того, чтобы перезаписать его, если он уже существует),

14
ответ дан 23 November 2019 в 02:41

В то время как GNU awk утилита обработки текста, она позволяет выполнять внешние команды оболочки через system() звонить. Мы можем использовать это в наших интересах как так:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

Идея здесь проста: мы читаем файл линию за линией, и из каждой строки мы создаем отформатированную строку cat "File name.txt", который затем передается system().

И здесь это в действии:

$ ls
file1.txt  file2.txt  file3 with space.txt  file_list.txt


$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3

Таким образом, мы уже сделали большую часть задачи там - мы распечатали все файлы в списке. Остальное просто: перенаправьте окончательный результат в файл с > оператор в сводный файл.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
4
ответ дан 23 November 2019 в 02:41

Другие вопросы по тегам:

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