您尚未登录。

#1 2016-12-28 14:05:35

alexxey
会员
注册时间: 2016-12-28
帖子: 73

关于如何自动转义字符的问题

大家好。在日常使用中,经常需要搜索硬盘上的文件,并对搜索的结果做处理。
例如打算在电子书库中寻找陈舜臣有关甲午战争的作品:

$ locate 陈舜臣 | grep 甲午
/mnt/ebook/Documents/K-历史_地理/K25_中国近代史/K256.3_甲午战争/batch2/[甲午战争]."日"陈舜臣.扫描版.pdf
/mnt/ebook/Documents/待整理/baidu/batch2-3/南阳高卧-近现代史大家/陈舜臣作品集/甲午战争 (日)陈舜臣 扫描版.pdf
/mnt/ebook/Documents/待整理/ishare/水隐醉月__7398/6001-6600/甲午战争 (日)陈舜臣 扫描版.pdf
/mnt/ebook/Documents/待整理/vdisk/史料与史实/陈舜臣 甲午战争.pdf

然后打算将这些文件全部复制到 /media/usb0/

locate 陈舜臣 | grep 甲午 | xargs cp -t /media/usb0

但文件名中有括号,空格,引号等特殊字符,无法直接作为 cp 的参数。
所以我设想有没有可能制作一个工具,自动转义字符。假设此程序名为 escape:

locate 陈舜臣 | grep 甲午 | escape | xargs cp -t /media/usb0

这样岂不方便?
谢谢!

离线

#2 2016-12-28 14:27:39

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: 关于如何自动转义字符的问题

locate -0 陈舜臣 | grep -z 甲午 | xargs -0 cp -t /media/usb0

离线

#3 2016-12-28 14:43:42

alexxey
会员
注册时间: 2016-12-28
帖子: 73

Re: 关于如何自动转义字符的问题

您好,我这样试了。不过得到了这样的结果

$ locate -0 陈舜臣 | grep -z 甲午
Binary file (standard input) matches
$ locate -0 陈舜臣 | grep -z 甲午 | xargs -0 cp -t /media/usb0
cp: cannot stat ‘Binary file (standard input) matches\n’: No such file or directory

离线

#4 2016-12-28 15:35:30

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: 关于如何自动转义字符的问题

你用的不是 Arch Linux?

grep --version 看看。

离线

#5 2016-12-28 15:50:56

alexxey
会员
注册时间: 2016-12-28
帖子: 73

Re: 关于如何自动转义字符的问题

非常感谢,刚才是在连接硬盘的arm板上试的,系统是 debian 8

$ grep --version
grep (GNU grep) 2.20
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

换了一台安装 grep (GNU grep) 2.27 机器,实验成功了。

离线

#6 2016-12-28 15:59:00

alexxey
会员
注册时间: 2016-12-28
帖子: 73

Re: 关于如何自动转义字符的问题

对于原来的想法还是不死心,试验了一下:

$ cat ../bin/escape
#!/bin/bash
while read line
do
  builtin printf "%q" "$line"
done < "${1:-/dev/stdin}"
$ echo "测 (试)" | escape
测\ \(试\)$ 
$ ls | grep 测
测试
测 (试)
测_试
测"试"
$ ls | grep 测 | escape
测试测\ \(试\)测_试测\"试\"$

分行没了,令人困惑。

离线

#7 2016-12-28 16:03:32

alexxey
会员
注册时间: 2016-12-28
帖子: 73

Re: 关于如何自动转义字符的问题

printf加上\n后还真有一定可行性

bin/escape:

#!/bin/bash
while read line
do
  builtin printf "%q\n" "$line"
done < "${1:-/dev/stdin}"

使用:

$ ls | grep 测
测试
测 '(试)'!
测 (试)
测_试
测"试"

$ ls | grep 测 | escape
测试
测\ \'\(试\)\'\!
测\ \(试\)
测_试
测\"试\"

$ ls | grep 测 | escape | xargs cp -vt testcp/
'测试' -> 'testcp/测试'
'测 '\''(试)'\''!' -> 'testcp/测 '\''(试)'\''!'
'测 (试)' -> 'testcp/测 (试)'
'测_试' -> 'testcp/测_试'
'测"试"' -> 'testcp/测"试"'

$ ls | grep 测 | escape | xargs cp -vt testcp/ | tee >(wc -l)
'测试' -> 'testcp/测试'
'测 '\''(试)'\''!' -> 'testcp/测 '\''(试)'\''!'
'测 (试)' -> 'testcp/测 (试)'
'测_试' -> 'testcp/测_试'
'测"试"' -> 'testcp/测"试"'
5

不知道这样有没有什么潜在的问题?

最近编辑记录 alexxey (2016-12-28 16:14:15)

离线

#8 2016-12-28 17:44:51

依云
会员
所在地: a.k.a. 百合仙子
注册时间: 2011-08-21
帖子: 8,384
个人网站

Re: 关于如何自动转义字符的问题

alexxey 说:

不知道这样有没有什么潜在的问题?

试试看,它满足了你 cp 的需求吗?

离线

#9 2016-12-28 22:20:41

alexxey
会员
注册时间: 2016-12-28
帖子: 73

Re: 关于如何自动转义字符的问题

依云 说:

试试看,它满足了你 cp 的需求吗?

还没有发现问题,不过担心会无法处理某些特殊情况。因此还是倾向于使用您在楼上讲的办法。

离线

页脚