具有修改的基本名称 {} 语法的复杂 find -exec

complex find -exec with modified basename {} syntax

设置

我有一个简单的 1 行 bash shell 脚本。它的目的是查找特定目录中的所有文件。对每个文件执行 curl POST.. 然后将文件移动到 "old" 目录。

当前尝试

下面是我正在使用的查找命令。为了便于阅读,我将把它放在多行中,但在我的脚本中它们都是同一行

sudo find . -type f 
-exec curl -vX POST -H "Content-Type: application/json" 
-H "Cache-Control: no-cache" -d @{} -u username:password 
"http://192.168.105.10/homeaccess/services/aCStats/uploadData?username=vangeeij&filename=$(basename {})" \; 
-exec sudo mv {} /home/vangeeij/acserver/resultsOld \;

问题

除了一个部分:

,命令的每一部分都按预期工作
&filename=$(basename {})

我已经尝试了所有我能想到的方法来让 find 命令的 {} 输出直接放在等号之后,而不是在文件前面有前导 ./名字.

前面的命令-d @{}我需要./但是这里我不需要

之前尝试过但失败了

filename=$(basename {})
filename=$('echo {} | sed "s|^\./||"')

老实说,这个清单还在继续……

问题

在上面的确切用法中,如何在 URL

中的 filename= 之后附加文件名,减去前导 ./

考虑使用 bash -c 来执行您的命令:

find . -type f -exec bash -c \
'curl -vX POST -H "Content-Type: application/json" \
-H "Cache-Control: no-cache" -d @{} -u username:password \
"http://192.168.105.10/homeaccess/services/aCStats/uploadData?username=vangeeij&filename=${1##*/} " \
-o /home/vangeeij/acserver/resultsOld/${1##*/}' _ {} \;

或作为一个班轮:

find . -type f -exec bash -c 'curl -vX POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d @{} -u username:password "http://192.168.105.10/homeaccess/services/aCStats/uploadData?username=vangeeij&filename=${1##*/} " -o /home/vangeeij/acserver/resultsOld/${1##*/}' _ {} \;

然后可以将文件名作为位置参数处理,您可以使用 Bash 参数扩展而不是 basename

您可以通过在 curl.

中使用 -o(输出)标志来避免使用 mv

Greg's wiki.

有关此技术的更多信息

我建议将 findcurl 更改为 bash 中的这个简单循环:

while IFS= read -d '' -r file; do
   base=$(basename "$file")
   curl -vX POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" \
      -d @"$file" -u username:password \
      "http://192.168.105.10/homeaccess/services/aCStats/uploadData?username=vangeeij&filename=$base"
   sudo mv "$file" /home/vangeeij/acserver/resultsOld
done < <(sudo find . -type f -print0)

我们在 while/done 循环中使用 进程替换 以获得这些好处:

  1. 它将处理由于使用 -print0while IFS= read -d '' -r file
  2. 而带有空格/glob 字符的文件
  3. 它将避免为每个文件创建子 shell,就像有问题的代码一样