次のコマンドを使用して、src フォルダーから dest フォルダーにファイルをコピーしています:
cp -nv /src/* /dest/ > copy_result.txt
コピーされたファイルの結果は、以下に示すように出力ファイルに表示されます。
« /src/test1.txt » -> « /dest/test1.txt »
« /src/test2.txt » -> « /dest/test2.txt »
それ以外の場合は、出力ファイルに、パス全体やファイル拡張子なしでファイル名のみが含まれるようにします。次のようになります。
test1
test2
答え1
コマンドを試してください
cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
awk
6 番目のフィールドを出力します。rev
文字列を反転します。cut
文字列を で指定された区切り文字で分割し-d
、 で指定された部分を抽出します-f
。
編集:
指摘されているように、これはスペースを含むファイル/ディレクトリには適していません。ただし、'-> « ' と ' »' の間の部分文字列を抽出することで対応できます。
cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt
答え2
-v
POSIX では指定されていません。つまり、各cp
実装では異なる方法で処理される可能性があります (またはまったく処理されない可能性があります)。 your がcp
と言っているのに対し« foo »
、 my が と言っているのです'foo'
。望ましくない出力を望ましい出力に変換するコマンドを作成することは可能ですが、実装に依存しないソリューションを提示したいと思いますcp
。
/src/*
コマンドを展開した後、cp
結果のエントリを1つずつコピーします。つまり、次のように変換できますcp -n /src/* /dest/
。
for file in /src/*; do cp -n "$file" /dest/; done
これで、 を使って何かを行うのは簡単になりました$file
。これにより、必要な出力が生成されます。
for path in /src/*; do
file="${path##*/}"
dst="/dest/$file"
[ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done
(ではなく をcopy_result.txt
使用するようにリダイレクトします)。done > copy_result.txt
done
cp -r -v
を使用し、 の展開からのオペランドの少なくとも 1 つが/src/*
ディレクトリである場合、cp
はその内容をコピーして出力しますが、上記のコード ( を追加した後-r
) は同じ内容をコピーしてディレクトリ自体のみを出力します。-r
が矛盾を生じさせる唯一のオプションではない可能性があります。
したがって、このアプローチはcp
実装から独立している必要がありますが、一部のオプションが使用されていないことに依存します。もう 1 つの欠点は、コードがcp
内のすべてのオブジェクトに対して個別のプロセスを実行することです/src/
。これは最適とは程遠いものです。
競合状態もあります。ファイルがと$dst
の間にある場合、がその役割を果たします。 を使用すると上書きを回避できますが、ファイルは引き続き報告されます。[
cp
cp
cp -n
printf