¿Cómo unir archivos de texto?

21

He guardado muchos documentos como txt. Quiero imprimirlos juntos, así que primero los quiero juntos en un solo archivo. El orden no importa en este caso.

Quiero una solución que no implique escribir los nombres de los archivos que se fusionarán, sino una que simplemente combine todos los archivos txt dentro de la carpeta.

¿Puedo hacerlo con un comando o alguna GUI?


Miré aquí . No se como usar join.


fuente

Respuestas:

43

Usar catcon redirección de salida. Sintaxis: cat file [file] [[file] ...] > joined-file.

Ejemplo con solo dos archivos (puede tener muchos más):

$ echo "some text in a file" > file1
$ echo "another file with some text" > file2
$ cat file1 file2 > mergedfiles
$ cat mergedfiles
some text in a file
another file with some text

En caso de que tenga "muchos documentos", utilice el patrón de concha (patrones):

cat input-files-dir/* > joined-file

Esto unirá todos los archivos en ese directorio al directorio actual (evitando que coincida con el archivo de salida). Es totalmente independiente del uso caty la redirección de salida: solo Bash proporciona todos los archivos como argumentos cat.


Tipos de archivo

Simplemente pegará (unirá) archivos juntos como lo haría con papel y cinta. No le importa que el formato de archivo real sea capaz de manejar esto. Funcionará para archivos de texto, pero no para PDF, ODT, etc. Bueno, los unirá, pero ya no es un PDF / ODT válido.


Orden de unión

Como señaló phoibos, el bloqueo de shell dará como resultado un orden alfabético de los nombres de los archivos. Así es como funciona Bash y shell globbing.


Anexo sobre input file is output fileerror

Cuando el patrón de los archivos de entrada coincide con el mismo archivo que el de salida, esto causará un error. Es una característica de seguridad. Ejemplo: cat *.txt > out.txtejecutar la segunda vez causará esto.

Lo que puedes hacer al respecto:

  • Elija un patrón más específico para que coincida con los archivos de entrada reales, que no coincida con el nombre de salida. Ejemplo: el patrón de los archivos de entrada *.txtcon el archivo de salida output.outno colisionará.
  • Trabaja en diferentes directorios. En el ejemplo anterior, he usado un input-files-dirdirectorio separado para colocar todos los archivos y enviarlos al directorio de trabajo actual. Esto hace que sea imposible obtener este error.
gertvdijk
fuente
@cipricus Sí, pero eso es muy básico (patrones). Pruebe sus patrones usando lssolo para enumerar las coincidencias. Por ejemplo, ls *.txtpara ver qué se compara.
gertvdijk
2
@cipricus ¿Qué tal cat * .txt> JoinedFile.txt?
Sadi
1
Esto es más sentido común en realidad, cat primero captura todos los archivos .txt y luego los une y, en tercer lugar, crea un nuevo archivo .txt que no se puede capturar en el primer paso ;-)
Sadi
1
@cipricus Simplemente une archivos. ¡Como lo haría usando trozos de papel con pegamento y cinta adhesiva! La mayoría de los formatos de archivo de "documentos" como PDF, que están comprimidos, no lo permiten. Utiliza un editor de PDF. Pero de todos modos, su pregunta era sobre archivos de texto .
gertvdijk
1
Entiendo completamente que el método que sugiere (crear un subdirectorio, mover archivos y luego unirlos) podría ser una mejor manera en algunos casos. Pero si solo queremos unir todos los archivos de texto (todos con extensión .txt) en el directorio actual cat * .txt> JoinedFile.txt hace el trabajo perfectamente. Simplemente lo probé por curiosidad y funciona, y parece que Cipricus también ha encontrado el mismo resultado. (Y el sistema ha comenzado a quejarse de que no deberíamos chatear aquí, de lo contrario, le preguntaría si puede enseñarle a este novato cómo puede usar el formato en estos comentarios sin una barra de herramientas ;-)
Sadi
12

Una forma simple de hacerlo es usando cat:

cat file1 file2 > joined_file

Si solo emite cat file1 file2, verá ambos archivos en la salida estándar. Al usar >, solo está redirigiendo la salida estándar a un archivo. Eso funcionará también con otros comandos.

Jorge Suárez de Lis
fuente
Por favor lea la pregunta. ¡Está diciendo que especifique nombres de archivos individuales, que el OP específicamente no quería hacer!
Sri
2
Eso no estaba en la pregunta original. No he actualizado mi respuesta desde que aparecieron respuestas más completas.
Jorge Suárez de Lis
@ JorgeSuárezdeLis Si bien esta respuesta no ayuda directamente a OP con su pregunta, tenga en cuenta que esta respuesta probablemente ayudará a alguien que solo tiene algunos archivos que les gustaría fusionar. (¡oh, hola, como yo! ¡gracias! ^ - ^) +1
Souta
@ JorgeSuárezdeLis De hecho. Has respondido perfectamente a la revisión 2 de la pregunta. Unos minutos más tarde, la revisión 3 , cambió los requisitos sobre las respuestas.
gertvdijk
5

Hazlo con un bucle simple:

for i in *.txt; do cat "$i" >> complete.txt; done

>> se agrega al archivo.

Nota: Si por alguna razón tiene que ejecutar el comando nuevamente, debe eliminarlo complete.txt, de lo contrario, escribiría el archivo en sí mismo, lo que no funciona.

phoibos
fuente
55
Esto también funcionará, pero no veo la necesidad de un bucle for si puedes usar argumentos para cat.
gertvdijk
1
Sí, tienes razón, por supuesto. Simplemente no estoy seguro sobre el orden de uso cat *.txt. El bucle for debe estar ordenado.
phoibos
Sí, es exactamente el mismo globo de concha. No importa si lo usa foren Bash o en cualquier otro lugar.
gertvdijk
4

Si los archivos que desea combinar terminan .txt, manténgalo simple:

cat *.txt > combined.txt

Si el directorio solo contiene archivos de texto, también es simple:

cat * > combined.txt

(Tenga en cuenta que una vez que cree combined.txt, hacerlo nuevamente lo incluiría en la expansión de *, lo que llevaría a un comportamiento extraño).

Si desea seleccionar algunos archivos en el directorio y no otros, es mejor si los nombres de archivo le permiten distinguir cuáles desea. Si no, puedes ponerte elegante find. Pero dudo que necesites ir tan lejos.

alexis
fuente
gracias. Si miras los comentarios a la respuesta aceptada, Sadi sugirió exactamente eso en un comentario. si tu respuesta hubiera sido la primera, la tuya habría sido lo que necesito. eche un vistazo a la mía también: agregó eso en el menú personalizado
Gracias por la respuesta. Sí, lo veo ahora, estaba un poco oscurecido ...
alexis
4

La secuencia de comandos de acción personalizada de Thunar escrita por cipricus también me inspiró a escribir una secuencia de comandos Nautilus similar y pensé que podría ser útil para otros que miran estas preguntas y respuestas como referencia sobre este tema. Asi que aqui esta:

#!/bin/sh
#Nautilus Script to join selected text files in a single file and open the joined file with default text editor
#
IFS=$'\n'
FILENAME="JoinedFile_$(date +%Y-%m-%d-%H-%M-%S).txt"
cat "$@" > "$FILENAME"
xdg-open "$FILENAME"
Sadi
fuente
@David Foerster Gracias por la edición. No tuve ningún problema con la versión anterior (con mis casos de prueba limitados) y tampoco veo ningún problema con esta versión mejorada. Lo siento si causé algún inconveniente debido a una falla en la versión anterior.
Sadi
No tenía fallas, pero contenía un bucle innecesario, lo que hacía que el código fuera más difícil de entender, en mi humilde opinión.
David Foerster
2

Este es un complemento y una variación de las otras respuestas, relacionadas con poner estas soluciones a trabajar en las acciones personalizadas de Thunar.

No todos son utilizables de esta manera, pero algunos sí.

Pensé que lo más interesante sería poder fusionar archivos seleccionados del menú contextual de Thunar .

Esta es una variación de lo que sugirió Sadi en un comentario a la respuesta de gertvdijk :

   cat %N > JoinedFile

Solo se unirán los archivos seleccionados. Restrinja las condiciones de apariencia a los archivos de texto.

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí


Un agradecimiento especial a Sadi cuyo comentario me proporcionó la solución más clara y actualizada a mi problema.

Acepté gertvdijk 's respuesta como definitivo. No solo fue la ocasión para el comentario de Sadi, sino que parece ser de mayor valor para otros, ya que proporciona una solución bien argumentada y completa (aunque algo por encima de mis habilidades de lectura de CLI).

Comunidad
fuente
2

Puedes probar el findcomando también,

find . -name "*.txt" -type f -exec cat {} + > file

Encuentra .txtarchivos dentro del directorio actual y ejecuta el catcomando en cada archivo fundado. Finalmente, toda la salida se redirigió al nombre del archivo file(creado dentro de la corriente directamente).

Explicación:

.                  # current directory

-name              # helps to find only .txt files.

-type f            # Only files

-exec cat {} +     # helps to run cat command on the founded .txt files.

>                  # Output redirection operator

file               # to store final output.
Avinash Raj
fuente