Shell-Script

簡單的文件循環 - ‘文件名太長’

  • August 30, 2022

我正在嘗試做最基本的事情:對特定文件夾中的所有文件執行一個或多個命令。

在這種情況下,它使用 macOS 的pstopdf命令將 eps 文件轉換為 PDF。

#!/bin/zsh

FILES=$(find "/Users/Ben/Pictures/Stock Illustrations" -type f)

for f in "$FILES"
do
  echo "$f"
  pstopdf "$f"
done

echo "$f"生成所有文件的正確列表;但隨後我得到了第二個文件列表 - 似乎來自pstopdf它本身** - 以 開頭File name too long: /Users/Ben/Pictures/Stock Illustrations/Flock wallpaper.eps,但其余文件已正確列出。

但是,該pstopdf命令不會創建任何 PDF 文件。

** 我試過註釋掉echoandpstopdf命令,所以我知道每個都會產生一個文件名列表。

如果我pstopdf <file.eps>在終端中執行,我不會得到 CLI 的輸出(例如,沒有列出文件名),但是會處理文件並創建一個 PDF 文件。

我敢說我可以xargsfind命令中使用,儘管我更喜歡帶有參數的循環的結構化方法,尤其是因為它提供了多個命令和其他邏輯的選項,並且更易於閱讀。

這裡有一個類似的問題:I get message “File name too long” when running for..in and touch

但我不明白答案如何適用。它說“或一個接一個地觸摸它們”(這是我想要的),但如果我這樣做:

FILES=/Users/Ben/Pictures/Stock\ Illustrations/*

我只是得到“沒有這樣的文件或目錄”。

FILES=$(find "/Users/Ben/Pictures/Stock Illustrations" -type f)
for f in "$FILES"

與連結的文章一樣,$FILES這是一個包含所有文件名的字元串。有了足夠的文件,單個文件名就太長了。只需幾個名稱,您就會嘗試訪問名稱中包含嵌入換行符的文件。

在這裡,您最好自己find呼叫pstopf,例如

$ find "/Users/Ben/Pictures/Stock Illustrations" -type f -print -exec pstopdf {} \;

如果你想在 find 的輸出上使用 shell 循環,你必須做這樣的事情(在 Bash 中,我沒有提到 zsh 那裡):

set -f      # disable globbing
IFS=$'\n'   # set IFS to just the newline (Bash/ksh/zsh, not POSIX)
files=$(find "/Users/Ben/Pictures/Stock Illustrations" -type f)
for f in $files; do
   echo "$f"
   pstopdf "$f"
done

或者find ... -print0 | while IFS= read -r -d '' f; do ...; done在 Bash 中使用。

或者for f in "/Users/Ben/Pictures/Stock Illustrations"/**/*; do ...在 Bash (with shopt -s globstar)、ksh 或 zsh 中使用 (shell 之間的細節有一些變化。

兩種 shell 解決方案都存在包含換行符的文件名問題,我希望你沒有,但遺憾的是允許文件名。

引用自:https://unix.stackexchange.com/questions/715453