symbolic remove mac link directories bash symlink

bash - remove - symlink windows



reemplazar todos los enlaces simbólicos con original (7)

Aquí hay una solución un poco más general, basada en @Daniel Haley

también conserva los enlaces simbólicos para referencia y le pide al usuario que seleccione un directorio para editar.

ls read -p ''Which directory do you want to update?: '' linkdir pushd $linkdir for linkname in $(find ./ -type l) do orig=$(readlink $linkname) mv $linkname ${linkname}.linkbak cp $orig $linkname done popd

Tengo la siguiente estructura de directorios

/symdir sym1 -> ../dir1 sym2 -> ../dir2 hello.txt

Y entonces

/dir1 some files here /dir2 more files

Me gustaría reemplazar los enlaces simbólicos en symdir (sym1, sym2) con los originales. Es decir

some_awesome_bash_func symdir symdir_output

Crearía

/symdir_output /dir1 some files here /dir2 more files hello.txt

¿Cómo lograría esto?


Lo hice de esta manera:

ls -la | awk ''/-/>/{system("rm "$10); system("cp "$12" .")}''

Cómo funciona:

ls -la produce algo como esto:

lrwxr-xr-x 1 username groupname 44 10 Oct 12:17 Queue.swift -> ../../../Platform/DataStructures/Queue.swift

La columna 10 es Queue.swift que es el nombre del archivo local.
La columna 12 es ../../../Platform/DataStructures/Queue.swift que es el nombre del destino del enlace

La primera parte del comando awk es ''/-/>/'' que significa "líneas de coincidencia que contienen -> usando una expresión regular

La siguiente parte del comando awk son dos llamadas al system

Primer system("rm "$10) que se expande al system("rm Queue.swift") .
Esto hará que el archivo original (el enlace simbólico) se elimine

El segundo es el system("cp "$12" .") Que se expande al system("cp ../../../Platform/DataStructures/Queue.swift .")

Poniéndolo todo junto, lo que sucede es para cada archivo (que es un enlace simbólico), primero eliminamos el enlace simbólico y luego copiamos el archivo de destino en su lugar.

Aunque no es parte de la pregunta original, estaba usando esto junto con git. Si también haces eso, puedes ejecutar git status . después y deberías ver un montón de cambios de tipo (y nada más), como este:

typechange: Queue.swift


Mi truco muy personal:

sed -i '''' **/*

Tenga en cuenta que estoy usando ** que usa la opción bash globstar, es posible que tenga que habilitarlo de antemano

shopt -s globstar


Probablemente no sea la mejor manera, pero funciona:

#!/usr/bin/bash for link in $(find /symdir -type l) do loc="$(dirname "$link")" dir="$(readlink "$link")" mv "$dir" "$loc" rm "$link" done


Puedes hacerlo fácilmente con rsync:

rsync symdir/ symdir_output/ -a --copy-links -v

(-a significa preservar básicamente todos los detalles sobre los archivos, --copy-links reemplaza -a para convertir los enlaces simbólicos en los archivos / directorios reales, y -v es para ver más detalladamente)

Editar:

Lo siento, mi solución no hace exactamente lo que pediste. Conservará los nombres del enlace simbólico en lugar de utilizar los nombres de destino. symdir_output tendría sym1 y sym2 en lugar de dir1 y dir2 (aunque sym1 y sym2 serían una copia real de dir1 y dir2). Espero que todavía funcione para ti.


Una respuesta relacionada, esta solución mantiene el archivo en su lugar original y crea una copia en lugar del enlace simbólico.

#/bin/bash for f in $(find . -maxdepth 1 -type l) do cp --remove-destination $(readlink -e $f) $f done


tl; dr: respuesta mucho más general, mucho más confiable:

find -type l -exec sh -c ''PREV=$(realpath -- "$1") && rm -- "$1" && cp -ar -- "$PREV" "$1"'' resolver {} /;

El enfoque "rsync-to-other-destination" es estrictamente superior y generalmente conduce a un mejor diseño.

La respuesta de @PinkFloyd no funciona con nombres de archivo inusuales, enlaces simbólicos "enterrados" o directorios con enlaces simbólicos. Vine aquí porque quería resolver los enlaces simbólicos de directorio, así que espero que otros también encuentren esta pregunta por este motivo. Además, mi versión de cp (GNU coreutils 8.25) no maneja correctamente --remove-destination para la respuesta de @ PinkFloyd para trabajar con directorios. Así que esta respuesta usa rm manual.

También tenga en cuenta:

  • ausencia de -rf . Esto se debe a que un enlace simbólico no es un directorio y no debería necesitar -r . Y a menos que tenga enlaces simbólicos con permisos restringidos (¡¿por qué querría eso ?!), tampoco necesita -f .
  • realpath está perfectamente bien en este contexto, porque nos permite averiguar la ubicación real en el sistema actual, en el contexto actual, y nada más importa. Esta ruta no se escribirá en el disco, por lo que no es un error.
  • la cadena de resolver es para sh . Ver man sh .
  • los guiones dobles en todas partes son necesarios, en caso de que algún enlace simbólico se llame --version o similar.
  • debido a la garantía de find ("el directorio principal aparece en algún lugar antes de su contenido"), esto reemplazaría primero al directorio principal y luego a cualquier enlace simbólico dentro del directorio de enlaces simbólicos. Así que funcionaría perfectamente bien con enlaces simbólicos "apilados".