Mam listę nazw plików w pliku o nazwie list_of_files.txt
.
Chcę skopiować zawartość każdego pliku z tej listy do innego pliku o nazwie all_compounds.sdf
.
Jak mam to zrobić z wiersza poleceń?
Mam listę nazw plików w pliku o nazwie list_of_files.txt
.
Chcę skopiować zawartość każdego pliku z tej listy do innego pliku o nazwie all_compounds.sdf
.
Jak mam to zrobić z wiersza poleceń?
Odpowiedzi:
Nie używaj prostego zastępowania poleceń, aby uzyskać nazwy plików (które mogłyby łatwo zerwać ze spacjami i innymi znakami specjalnymi). Użyj czegoś takiego xargs
:
xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf
Lub while read
pętla:
while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf
Aby bezpiecznie korzystać z podstawiania poleceń, ustaw przynajmniej IFS
nową linię i wyłącz globowanie (rozwijanie symboli wieloznacznych):
(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)
Nawias otaczający ()
powinien uruchomić to w podpowłoce, aby te zmiany nie wpłynęły na twoją bieżącą powłokę.
Szybki i brudny sposób ...
cat $(cat list_of_files.txt) >> all_compounds.sdf
Uwaga: działa to tylko wtedy, gdy nazwy plików na liście są bardzo dobrze zachowane - wszystko pójdzie źle, jeśli będą miały spacje, znaki nowej linii lub znaki mające specjalne znaczenie dla powłoki - użyj tej odpowiedzi, aby uzyskać wiarygodne wyniki)
cat
con cat tworzy pliki. Drukuje również ich zawartość.command2 $(command1)
, możesz przekazać dane wyjściowe command1
( cat list...
) na command2
( cat
), które łączą pliki.Następnie użyj przekierowania, >>
aby wysłać dane wyjściowe do pliku zamiast drukowania na standardowe wyjście. Jeśli chcesz zobaczyć wynik, użyj tee
zamiast tego:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(Użyłem >>
zamiast >
i tee
z -a
przełącznikiem, jeśli Twój plik już istnieje - to dołącza się do pliku zamiast nadpisywać go, jeśli już istnieje)
cat
pobiera całą listę jako jeden argument.
Chociaż GNU awk
jest narzędziem do przetwarzania tekstu, pozwala na uruchamianie zewnętrznych poleceń powłoki poprzez system()
wywołanie. Możemy to wykorzystać na naszą korzyść:
$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt
Pomysł jest prosty: odczytujemy plik linia po linii i z każdej linii tworzymy sformatowany ciąg cat "File name.txt"
, który jest następnie przekazywany do system()
.
I oto jest w akcji:
$ 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
Tak więc wykonaliśmy już dużą część zadania - wydrukowaliśmy wszystkie pliki z listy. Reszta jest prosta: przekieruj ostateczne wyjście do pliku z >
operatorem do pliku podsumowania.
awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
"$(cat list_of_files.txt)"