bash - 如何在unix中复制包含空格的文件名/路径?
问题描述
我的目标是搜索包含模式的文件并将其复制到文件夹中。这些文件可能在一个文件夹的多个文件夹中可用(例如 /home/abc/logs/ ....)。一些文件名和文件夹带有空格字符,包括空格。我正在尝试将找到的结果分配给一个变量并复制它。但结果是“参数列表太长”
Linux 服务器
pattern="somesttring" ;
LOG_FILE_PATH="/path/to/logs/"
LOGS_TO_COPY=$(grep -Hrn "$pattern" "$LOG_FILE_PATH" | cut -d: -f1)
cp $LOGS_TO_COPY temp #temp is folder to which i have to copy
我收到以下错误:
cp $LOGS_TO_COPY temp/
-bash: /bin/cp: Argument list too long
解决方案
不要将它存储在变量中,至少不是普通的字符串变量。字符串变量无法保持每个参数内的空格与分隔它们的空格之间的差异。
grep -lr "$pattern" "$LOG_FILE_PATH" | while IFS= read -r file; do cp "$file" temp/; done
另请注意,您不需要剪切 grep 结果,因为该-l
标志只为您提供文件名,正是您想要的。-H
是默认设置,因此不需要它,-n
如果您只是要切断它,则不需要它。
如果您的文件名称中包含换行符,这将不起作用。作为一种解决方案,您可以告诉grep
(and read
) 使用 NUL 作为分隔符。
grep -lr --null "$pattern" "$LOG_FILE_PATH" | while IFS= read -d $'\0' -r file; do cp "$file" temp/; done
或者,您可以使用xargs
而不是while
+ read
:
grep -lr --null "$pattern" "$LOG_FILE_PATH" | xargs --null -I {} cp {} temp/
如果必须将其存储在变量中,请使用与上述相同的模式将其存储到数组变量中。这种方式不需要空格作为参数分隔符。
declare -a files
while IFS= read -d $'\0' -r file; do files+=("$file"); done < <(grep -lr --null "$pattern" "$LOG_FILE_PATH")
cp "${files[@]}" temp/
这是另一种方法(尽管如果文件名包含换行符,这将不起作用,因为mapfile
不支持更改分隔符):
mapfile -t files < <(grep -lr "$pattern" "$LOG_FILE_PATH")
cp "${files[@]}" temp/
如果要复制的文件数量很大,则while
和xargs
解决方案仍然有效,但那些简单地将整个数组放入一个cp
命令的解决方案可能不会。
推荐阅读
- ansible - 无法计算远程文件的校验和,validate_checksum 等于 false/no
- javascript - 不确定在组件状态下更新嵌套对象属性时如何触发 useEffect
- javascript - Node js渲染多个静态方法
- c - 未找到版本“libssl.so.10”
- tomcat - 使用 groovy、ant 和 jmx 重新加载 Tomcat SSL 协议
- json - 使用 Flask + GeoAlchemy2 应用程序返回有效的 GeoJSON
- c - 无法编译,使用ubuntu构建c代码
- python - 是否可以在 python 中使用 ALTAIR 4.1 制作等高线图?
- flutter - 从 Flutter 中删除底部导航栏上的默认填充或边距
- javascript - 正则表达式匹配单独或单个大写字母