3

我有一个 bash/shell 函数,它应该查找文件,然后 awk/将它找到的第一个文件复制到另一个目录。不幸的是,如果包含 的目录file名称中有空格,那么整个事情都会失败,因为它会出于某种原因截断路径。我如何解决它?

如果 file.txt 在 /path/to/search/中,空格是错误的/ 它会失败。

dir=/path/to/destination/ | find /path/to/search -name file.txt | head -n 1 | awk -v dir="$dir" '{printf "cp \"%s\" \"%s\"\n", $1, dir}' | sh

cp: /path/to/search/spaces: No such file or directory

*如果 file.txt 位于 /path/to/search/ spacesarebad / 它可以工作,但请注意没有空格。:-/

4

3 回答 3

3

awk 的默认分隔符是空格。只需通过执行以下操作将其更改为其他内容:

awk -F"\t" ...

您的脚本应如下所示:

dir=/path/to/destination/ | find /path/to/search -name file.txt | head -n 1 | awk -F"\t" -v dir="$dir" '{printf "cp \"%s\" \"%s\"\n", $1, dir}' | sh

正如评论所指出的,您实际上并不需要所有这些步骤,您实际上可以简单地执行(单行):

dir=/path/to/destination/ && path="$(find /path/to/search -name file.txt | head -n 1)" && cp "$path" "$dir"

格式化代码(可能看起来更好,在这种情况下^^):

dir=/path/to/destination/
path="$(find /path/to/search -name file.txt | head -n 1)"
cp "$path" "$dir"

""用于将字符串的全部内容分配给变量,导致默认情况下为空格的分隔符不IFS被考虑在字符串上。

于 2013-01-02T22:18:53.307 回答
2

如果您认为空格不好,请等到换行遇到麻烦。考虑例如:

mkdir spaces\ are\ bad
touch spaces\ are\ bad/file.txt
mkdir newlines$'\n'are$'\n'even$'\n'worse
touch newlines$'\n'are$'\n'even$'\n'worse/file.txt

和:

find . -name file.txt                                   

head 命令采用换行符分隔符。您可以通过使用分隔符来解决 GNU find 和 GNU grep(可能是其他)的空格和换行问题\0

find . -name file.txt -print0 | grep -zm1 . | xargs -0 cp -t "$dir"
于 2013-01-02T22:37:26.133 回答
0

你可以试试这个。

awk '{print substr($0, index($0,$9))}'

例如,这是 ls 命令的输出:

-rw-r--r--。1 根 73834496 12 月 6 日 10:55 带空格的文件 2

如果你像这样使用简单的 awk

# awk '{print $9}'

它只返回

# File

如果与完整命令一起使用

# awk '{print substr($0, index($0,$9))}'

我得到了整个输出

带空格的文件 2

这里 substr(s, a, b) :它从字符串 s 返回 b 个字符,从位置 a 开始。参数 b 是可选的。

例如,如果匹配是 addr:192.168.1.133 并且您使用 substr 如下

# awk '{print substr($2,6)}'

你得到 IP 即 192.168.1.133。注意 6 是从 a in addr 开始的字符

因此,在正确的命令中, $2 是 $0 (打印整行。)并且 index($0,$9) 匹配 $9 并打印第 9 列之前的所有内容。您可以将其更改为 index($0,$8) 并查看输出更改到

# 10:55 File with spaces 2

`index(IN, FIND)' 这会在字符串 IN 中搜索字符串 FIND 的第一次出现,并返回该出现在字符串 IN 中的开始位置(以字符为单位)。

我希望它有所帮助。此外,如果您将此值分配给脚本中的变量,则需要将变量括在双引号中。否则,如果您对提取的文件名执行其他操作,您将收到错误。

于 2016-12-06T06:53:01.563 回答