我有一个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 /它可以正常工作,但请注意没有空格。 : - /
答案 0 :(得分: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
(默认情况下为空格)不会被视为字符串。
答案 1 :(得分: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命令假定换行符分隔符。你可以使用\0
分隔符来解决GNU find和GNU grep(也许是其他人)的空格和换行问题:
find . -name file.txt -print0 | grep -zm1 . | xargs -0 cp -t "$dir"
答案 2 :(得分:0)
你可以试试这个。
awk '{print substr($0, index($0,$9))}'
例如,这是ls命令的输出:
-rw-R - R--。 1 root root 73834496 Dec 6 10:55带空格的文件2
如果你使用像这样的简单awk
# awk '{print $9}'
仅返回
# File
如果与完整命令一起使用
# awk '{print substr($0, index($0,$9))}'
我得到了整个输出
下面 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是从in addr
开始的字符因此,在正确的命令中,$ 2为$ 0(打印整行。)和index($ 0,$ 9)匹配$ 9并在第9列之前打印所有内容。您可以将其更改为索引($ 0,$ 8)并查看输出变为
# 10:55 File with spaces 2
`index(IN,FIND)' 这将在字符串IN中搜索第一次出现的字符串 查找并返回该位置的字符位置 从字符串IN开始。
我希望它有所帮助。此外,如果要将此值分配给脚本中的变量,则需要将变量括在双引号中。另外,如果您对提取的文件名进行其他操作,则会出现错误。