如何在 unix 中复制包含空格的文件 name/path?
How to copy files name/path containing spaces in unix?
我的目标是搜索包含模式的文件并将其复制到文件夹中。这些文件可能在一个文件夹中的许多文件夹中可用(比如 /home/abc/logs/ ....)。一些文件名和文件夹带有空格字符,包括空格。我正在尝试将找到的结果分配给一个变量并复制它。但结果是 "Argument list too long"
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
不要将它存储在变量中,至少不是普通的字符串变量。字符串变量无法保持每个参数内部的 space 与分隔它们的 space 之间的差异。
grep -lr "$pattern" "$LOG_FILE_PATH" | while IFS= read -r file; do cp "$file" temp/; done
另请注意,您不需要剪切 grep 结果,因为 -l
标志只为您提供文件名,正是您想要的。 -H
是默认值,因此不需要,如果您只是想将其切断,则 -n
是不必要的。
如果您的文件名称中包含换行符,这将不起作用。作为解决方案,您可以告诉 grep
(和 read
)使用 NUL 作为分隔符。
grep -lr --null "$pattern" "$LOG_FILE_PATH" | while IFS= read -d $'[=11=]' -r file; do cp "$file" temp/; done
或者,您可以使用 xargs
而不是 while
+read
:
grep -lr --null "$pattern" "$LOG_FILE_PATH" | xargs --null -I {} cp {} temp/
如果您必须将其存储在变量中,请使用与上述相同的模式将其存储到数组变量中。这样就不需要 space 作为参数分隔符。
declare -a files
while IFS= read -d $'[=13=]' -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
命令的方法可能没有。
我的目标是搜索包含模式的文件并将其复制到文件夹中。这些文件可能在一个文件夹中的许多文件夹中可用(比如 /home/abc/logs/ ....)。一些文件名和文件夹带有空格字符,包括空格。我正在尝试将找到的结果分配给一个变量并复制它。但结果是 "Argument list too long"
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
不要将它存储在变量中,至少不是普通的字符串变量。字符串变量无法保持每个参数内部的 space 与分隔它们的 space 之间的差异。
grep -lr "$pattern" "$LOG_FILE_PATH" | while IFS= read -r file; do cp "$file" temp/; done
另请注意,您不需要剪切 grep 结果,因为 -l
标志只为您提供文件名,正是您想要的。 -H
是默认值,因此不需要,如果您只是想将其切断,则 -n
是不必要的。
如果您的文件名称中包含换行符,这将不起作用。作为解决方案,您可以告诉 grep
(和 read
)使用 NUL 作为分隔符。
grep -lr --null "$pattern" "$LOG_FILE_PATH" | while IFS= read -d $'[=11=]' -r file; do cp "$file" temp/; done
或者,您可以使用 xargs
而不是 while
+read
:
grep -lr --null "$pattern" "$LOG_FILE_PATH" | xargs --null -I {} cp {} temp/
如果您必须将其存储在变量中,请使用与上述相同的模式将其存储到数组变量中。这样就不需要 space 作为参数分隔符。
declare -a files
while IFS= read -d $'[=13=]' -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
命令的方法可能没有。