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 parash
. Verman 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".