具有修改的基本名称 {} 语法的复杂 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
有关此技术的更多信息
我建议将 find
和 curl
更改为 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
循环中使用 进程替换 以获得这些好处:
- 它将处理由于使用
-print0
和 while IFS= read -d '' -r file
而带有空格/glob 字符的文件
- 它将避免为每个文件创建子 shell,就像有问题的代码一样
设置
我有一个简单的 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
有关此技术的更多信息
我建议将 find
和 curl
更改为 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
循环中使用 进程替换 以获得这些好处:
- 它将处理由于使用
-print0
和while IFS= read -d '' -r file
而带有空格/glob 字符的文件
- 它将避免为每个文件创建子 shell,就像有问题的代码一样