Estou copiando arquivos da pasta src para a pasta dest usando o comando:
cp -nv /src/* /dest/ > copy_result.txt
O resultado dos arquivos copiados está no arquivo de saída conforme mostrado abaixo:
« /src/test1.txt » -> « /dest/test1.txt »
« /src/test2.txt » -> « /dest/test2.txt »
Caso contrário, quero que o arquivo de saída contenha apenas o nome do arquivo, sem o caminho completo e sem a extensão do arquivo, assim:
test1
test2
Responder1
Experimente o comando
cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
awk
imprime o sexto campo. E rev
inverte a string. cut
divide a string em um delimitador especificado por -d
, extrai a parte especificada por -f
.
Editar:
Como apontado, isso não é amigável com arquivos/diretórios com espaços. Mas isso será feito extraindo substrings entre '-> « ' e ' »' :
cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
Responder2
-v
não é especificado pelo POSIX. Isso significa que cada cp
implementação pode lidar com isso de maneira diferente (ou não). Onde o seu cp
diz « foo »
o meu diz 'foo'
. É possível criar um comando que transforme sua saída indesejada na desejada, mas gostaria de apresentar uma solução independente da cp
implementação.
Depois que /src/*
seu comando se expandir, cp
copie as entradas resultantes uma por uma. Isso significa que você pode se transformar cp -n /src/* /dest/
em
for file in /src/*; do cp -n "$file" /dest/; done
Agora é fácil fazer algo com $file
. Isso irá gerar a saída que você deseja:
for path in /src/*; do
file="${path##*/}"
dst="/dest/$file"
[ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done
(Para redirecionar para copy_result.txt
usar done > copy_result.txt
em vez de apenas done
).
Observe que se você usasse cp -r -v
e pelo menos um dos operandos da expansão /src/*
fosse um diretório, cp
copiaria e imprimiria seu conteúdo, enquanto o código acima (após adicionarmos -r
) copiaria o mesmo, mas imprimiria apenas o próprio diretório. -r
pode não ser a única opção que introduziria discrepância.
Portanto, embora a abordagem deva ser independente da cp
implementação, ela depende da(s) utilização(ões) de algumas opções. Outra desvantagem é que o código executa um cp
processo separado para cada objeto /src/
, o que está longe de ser o ideal.
Há também uma condição de corrida: se o $dst
arquivo aparecer entre [
e cp
, cp
fará seu trabalho. Você pode usar cp -n
para evitar a substituição, mas printf
ainda assim reportará o arquivo.