如何僅將檔案名稱顯示為 cp 命令的輸出?

如何僅將檔案名稱顯示為 cp 命令的輸出?

我使用以下命令將文件從 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

-vPOSIX 沒有指定。這意味著每個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.txtusedone > copy_result.txt而不僅僅是done)。


請注意,如果您使用cp -r -v的擴充功能中的至少一個操作數/src/*是一個目錄,cp則會複製並列印其內容,而上面的程式碼(在新增之後-r)將複製盡可能多的內容,但僅列印目錄本身。-r可能不是導致差異的唯一選擇。

因此,雖然該方法應該獨立於cp實現,但它依賴於某些未使用的選項。另一個缺點是程式碼cp為 中的每個物件運行一個單獨的進程/src/,這遠非最佳。

還有一個競爭條件:如果$dst文件出現在[和之間cpcp則將完成其工作。您可以使用cp -n以避免覆蓋,但printf仍會報告該文件。

相關內容