我使用以下命令將文件從 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
列印第六個字段。並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
實作可能會以不同的方式處理它(或根本不處理)。你cp
說的« foo »
我說的'foo'
。可以製作一個命令將不需要的輸出轉換為所需的輸出,但我仍然想提出一個獨立於cp
實現的解決方案。
/src/*
在命令展開後,cp
將結果條目一一複製。這意味著你可以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
usedone > copy_result.txt
而不僅僅是done
)。
請注意,如果您使用cp -r -v
的擴充功能中的至少一個操作數/src/*
是一個目錄,cp
則會複製並列印其內容,而上面的程式碼(在新增之後-r
)將複製盡可能多的內容,但僅列印目錄本身。-r
可能不是導致差異的唯一選擇。
因此,雖然該方法應該獨立於cp
實現,但它依賴於某些未使用的選項。另一個缺點是程式碼cp
為 中的每個物件運行一個單獨的進程/src/
,這遠非最佳。
還有一個競爭條件:如果$dst
文件出現在[
和之間cp
,cp
則將完成其工作。您可以使用cp -n
以避免覆蓋,但printf
仍會報告該文件。