Shell-Script

如何獲得此“for”循環所需的輸入?

  • July 29, 2020

我編寫了一個小腳本來備份 TOR 的下載,因為偶爾 TOR 會嘗試合併其占位符文件(具有原始文件名的零字節文件)及其實際下載文件(原始文件加.part副檔名),這將導致在所有數據失去的情況下。

.part作為此腳本的補充,我希望腳本在下載完成後刪除備份的文件。問題是下載的文件名通常包含空格或特殊字元,迫使我使用雙引號,這很好用,直到我下載了多個文件,此時find將所有文件展開在一行上,我的測試語句。

也許我對此的方法都是錯誤的,但如果不是,我怎樣才能獲得rm命令的單獨文件名?

#!/system/bin/sh
if [ ! -d /sdcard/Download/tordownloadbackup ]; then
mkdir /sdcard/Download/tordownloadbackup
fi
echo 'backing-up'
find /sdcard/Download/ -maxdepth 1 -name '*.part' -print -exec cp {} /sdcard/Download/tordownloadbackup/ \;

for f in "`find /sdcard/Download/tordownloadbackup/ -type f |rev |cut -c 6-100| cut -d / -f 1 |rev`"; do

if [ -s /sdcard/Download/"$f" ]; then
   if [ -f /sdcard/Download/tordownloadbackup/"$f".part ]; then
   rm /sdcard/Download/tordownloadbackup/"$f".part
   d="$f".part
   echo "deleting $d"
   fi
fi
done
sleep 300
~/run.sh

如果您確定文件名中沒有換行符,那麼您可以這樣做:

find /sdcard/Download/tordownloadbackup/ -type f -printf '%f\n' |
   awk '{ print substr($0,1,length($0)-5); }' |
   while IFS= read -r filename; do
       : ...
   done

使用路徑中的任何字元的一般方法是:

find . -exec bash -c 'ls -l "$@"' bash {} +

這個命令:

for f in "`find /sdcard/Download/tordownloadbackup/ -type f | ...

看起來很尷尬並且容易出錯。真的不鼓勵使用for.

遍歷find在 bash 中找到的文件的最可靠方法是使用 aread和 null 終止的字元串。< <(command)在 之後使用while將命令的輸出通過管道傳輸到read中,這稱為程序替換

while IFS= read -r -d $'\0' file; do
   # Arbitrary operations on "$file" here
done < <(find /some/path -type f -print0)

對@SiegeX 的舊答案表示敬意:https ://stackoverflow.com/questions/8677546/reading-null-delimited-strings-through-a-bash-loop

而且,rev |cut -c 6-100| cut -d / -f 1 |rev看起來很奇怪。我認為這應該列印目錄基本名稱。請為此使用 bash 內置字元串操作或dirnameand basename

因此,您最終可能會將此循環重寫為(使用字元串操作,因為內置而更快):

while IFS= read -r -d $'\0' file; do
 Filebasename="${file##*/}"
 Dirname="${file%/*}"
 Dirbasename="${Dirname##*/}"
 # other stuff here
done < <(find /sdcard/Download/tordownloadbackup/ -type f -print0)

有關刪除子字元串的更多資訊,請參閱Linux 文件項目

或使用basenameand dirname(因為外部程序而變慢):

while IFS= read -r -d $'\0' file; do
 Dirbasename="$(basename -- "$(dirname -- "$file")")"
 # other stuff here
done < <(find /sdcard/Download/tordownloadbackup/ -type f -print0)

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