Como exibir o nome do arquivo apenas como saída do comando cp?

Como exibir o nome do arquivo apenas como saída do comando cp?

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

awkimprime o sexto campo. E revinverte a string. cutdivide 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

-vnão é especificado pelo POSIX. Isso significa que cada cpimplementação pode lidar com isso de maneira diferente (ou não). Onde o seu cpdiz « 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 cpimplementação.


Depois que /src/*seu comando se expandir, cpcopie 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.txtusar done > copy_result.txtem vez de apenas done).


Observe que se você usasse cp -r -ve pelo menos um dos operandos da expansão /src/*fosse um diretório, cpcopiaria 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. -rpode não ser a única opção que introduziria discrepância.

Portanto, embora a abordagem deva ser independente da cpimplementação, ela depende da(s) utilização(ões) de algumas opções. Outra desvantagem é que o código executa um cpprocesso separado para cada objeto /src/, o que está longe de ser o ideal.

Há também uma condição de corrida: se o $dstarquivo aparecer entre [e cp, cpfará seu trabalho. Você pode usar cp -npara evitar a substituição, mas printfainda assim reportará o arquivo.

informação relacionada