У меня есть список имен файлов внутри файла с именем list_of_files.txt.
Я хочу скопировать содержимое каждого файла в этом списке в другой файл с именем all_compounds.sdf .
Как я должен сделать это из командной строки?
У меня есть список имен файлов внутри файла с именем list_of_files.txt.
Я хочу скопировать содержимое каждого файла в этом списке в другой файл с именем all_compounds.sdf .
Как я должен сделать это из командной строки?
Ответы:
Не используйте простую подстановку команд для получения имен файлов (которые могут легко разрываться с пробелами и другими специальными символами). Используйте что-то вроде 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только новую строку и отключите глобализацию (расширение по шаблону):
(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)
Круглые скобки ()должны запускать это в подоболочке, чтобы эти изменения не повлияли на вашу текущую оболочку.
Быстрый и грязный способ ...
cat $(cat list_of_files.txt) >> all_compounds.sdf
Обратите внимание: это работает только в том случае, если имена файлов в вашем списке очень хорошо себя ведут - все пойдет не так, если они содержат пробелы, символы новой строки или любые символы, которые имеют особое значение для оболочки - используйте вместо этого ответ для получения надежных результатов)
catcon cat создает файлы. Он также печатает их содержимое.command2 $(command1)вы можете передать вывод command1( cat list...) в command2( cat), который объединяет файлы.Затем используйте перенаправление >>для отправки вывода в файл вместо печати на стандартный вывод. Если вы хотите увидеть вывод, используйте teeвместо этого:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf(Я использовал >>вместо >и teeс -aпереключателем, если ваш файл уже существует - он добавляется к файлу, а не перезаписывает его, если он уже существует)
catвесь список получает как один аргумент.
Хотя 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
"$(cat list_of_files.txt)"