xargs 不适用于 SUSE
xargs doesn't work on SUSE
This problem occurs only on suse, it works on ubuntu and even on windows through babun
我的意思是用另一个词替换几个文件中的一个词。
这就是我正在尝试的:
$ grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs sed -i 's/MY_PATTERN/NEW_WORD/g'
sed: can't read path/to/a/found/file_1: No such file or directory
sed: can't read path/to/a/found/file_2: No such file or directory
sed: can't read path/to/a/found/file_3: No such file or directory
...
知道
$ grep -Inrs MY_PATTERN src/ | cut -d: -f1
path/to/a/found/file_1
path/to/a/found/file_2
path/to/a/found/file_3
更新1
这也不行
$ grep -lZ -Irs MY_PATTERN src/ | xargs -0 ls
ls: cannot access path/to/a/found/file_1: No such file or directory
ls: cannot access path/to/a/found/file_2: No such file or directory
ls: cannot access path/to/a/found/file_3: No such file or directory
...
$ ls -al path/to/a/found/file_1 | cat -vet
-rw-r--r-- 1 webme 886 Feb 1 13:36 path/to/a/found/file_1$
更新2
$ whoami
webme
$ uname -a
Linux server_vm_id_34 3.0.101-68-default #1 SMP Tue Dec 1 16:21:37 UTC 2015 (ed01a9f) x86_64 x86_64 x86_64 GNU/Linux
更新3
$ grep --version
grep (GNU grep) 2.7
Copyright (C) 2010 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>.
$ xargs --version
xargs (GNU findutils) 4.4.0
Copyright (C) 2007 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 Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
# My project path /home/users/webme/projects/my_project
$ df -T
dl360d-01:/homeweb/users/webme nfs 492625920 461336576 31289344 94% /home/users/webme
$ id
uid=1689(webme) gid=325(web) groups=325(web)
$ mount -v
/dev/vda2 on / type btrfs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,mode=1777)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/vda1 on /boot type ext3 (rw,acl,user_xattr)
/dev/vdb on /appwebinet type xfs (rw)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
dl360d-01:/homeweb/users on /homeweb/users type nfs (rw,soft,bg,addr=xx.xx.xx.xx)
dl360d-01:/appwebinet/tools/list on /appwebinetdev/tools/list type nfs (ro,soft,sloppy,addr=xx.xxx.xx.xx)
dl360d-01:/homeweb/users/webme on /home/users/webme type nfs (rw,soft,bg,addr=xx.xxx.xx.xx)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
none on /var/lib/ntp/proc type proc (ro,nosuid,nodev)
我没有exportfs
,我在sudo zypper install exportfs
中也没有
是这种情况下最简单、最可靠的解决方案。
这个 答案可能仍然对 (a) -d
与 -n
选项的讨论以及 (b) 如何 preview xargs
将执行的命令。
据我了解,SUSE 使用 GNU 实用程序,因此您可以 使用 xargs -d'\n'
:
grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs -d'\n' sed -i 's/MY_PATTERN/NEW_WORD/g'
xargs -d'\n'
确保 每个输入行 作为一个整体 被视为它自己的参数(保留带空格的文件名的完整性),同时仍然传递尽可能多的参数(通常,全部)一次。
(相比之下,-n 1
会用空格分隔参数,并一次用 1 个参数调用目标命令。)
如果你想预览将执行的命令,使用辅助. bash
命令:
grep -Inrs MY_PATTERN src/ | cut -d: -f1 |
xargs -d'\n' bash -c 'printf "%q " "$@"' _ sed -i 's/MY_PATTERN/NEW_WORD/g'
继续阅读以获得解释。
可选的背景信息。
xargs
有自己的选项,-p
,用于预览要执行的命令 和 提示确认,但预览 没有反映参数边界 的方式直接从 [=113= 调用命令时必须指示它们].
一个简单的例子:
$ echo 'hi, there' | xargs -p -d '\n' printf '%s'
printf %s hi, there ?...
xargs
实际上执行的是printf '%s' 'hi, there'
的等价,但那是没有反映在-p
的提示中。
解决方法:
$ echo 'hi, there' | xargs -d '\n' bash -c 'printf "%q " "$@"' _ printf '%s'
printf %s hi\,\ there
通用辅助 bash
命令 - bash -c 'printf "%q " "$@"' _
,插入到目标命令之前 - 引用 xargs
传递的参数 - on需求,仅在必要时 - 以 shell 需要的方式将每个识别为 单个参数 ,并加入他们有空格。
最终结果是 a shell command 被打印出来,即 equivalent what xargs
将执行 (尽管如您所见,不能保证保留输入的引用样式)。
我建议保持简单:
$ grep -lZ -Irs foo * | xargs -0 sed -i 's/foo/bar/g'
grep -l
只输出匹配的文件名,这正是您在此管道中想要的。 grep -Z
以 NUL
终止每个匹配的文件名,xargs -0
可以选择。这允许嵌入 white-space 的文件名在 grep 和 xargs 之间不受限制地传递。
# show the structure
$ tree
.
└── path
└── to
└── a
└── found
├── file_1
├── file_2
└── file_3
# show the contents
$ grep . path/to/a/found/file_*
path/to/a/found/file_1:a foo bar
path/to/a/found/file_2:a foo bar
path/to/a/found/file_3:a foo bar
# try it out
$ grep -lZ -Irs foo * | xargs -0 ls -l
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_1
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_2
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_3
This problem occurs only on suse, it works on ubuntu and even on windows through babun
我的意思是用另一个词替换几个文件中的一个词。
这就是我正在尝试的:
$ grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs sed -i 's/MY_PATTERN/NEW_WORD/g'
sed: can't read path/to/a/found/file_1: No such file or directory
sed: can't read path/to/a/found/file_2: No such file or directory
sed: can't read path/to/a/found/file_3: No such file or directory
...
知道
$ grep -Inrs MY_PATTERN src/ | cut -d: -f1
path/to/a/found/file_1
path/to/a/found/file_2
path/to/a/found/file_3
更新1
这也不行
$ grep -lZ -Irs MY_PATTERN src/ | xargs -0 ls
ls: cannot access path/to/a/found/file_1: No such file or directory
ls: cannot access path/to/a/found/file_2: No such file or directory
ls: cannot access path/to/a/found/file_3: No such file or directory
...
$ ls -al path/to/a/found/file_1 | cat -vet
-rw-r--r-- 1 webme 886 Feb 1 13:36 path/to/a/found/file_1$
更新2
$ whoami
webme
$ uname -a
Linux server_vm_id_34 3.0.101-68-default #1 SMP Tue Dec 1 16:21:37 UTC 2015 (ed01a9f) x86_64 x86_64 x86_64 GNU/Linux
更新3
$ grep --version
grep (GNU grep) 2.7
Copyright (C) 2010 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>.
$ xargs --version
xargs (GNU findutils) 4.4.0
Copyright (C) 2007 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 Eric B. Decker, James Youngman, and Kevin Dalley.
Built using GNU gnulib version e5573b1bad88bfabcda181b9e0125fb0c52b7d3b
# My project path /home/users/webme/projects/my_project
$ df -T
dl360d-01:/homeweb/users/webme nfs 492625920 461336576 31289344 94% /home/users/webme
$ id
uid=1689(webme) gid=325(web) groups=325(web)
$ mount -v
/dev/vda2 on / type btrfs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,mode=1777)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/vda1 on /boot type ext3 (rw,acl,user_xattr)
/dev/vdb on /appwebinet type xfs (rw)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
dl360d-01:/homeweb/users on /homeweb/users type nfs (rw,soft,bg,addr=xx.xx.xx.xx)
dl360d-01:/appwebinet/tools/list on /appwebinetdev/tools/list type nfs (ro,soft,sloppy,addr=xx.xxx.xx.xx)
dl360d-01:/homeweb/users/webme on /home/users/webme type nfs (rw,soft,bg,addr=xx.xxx.xx.xx)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
none on /var/lib/ntp/proc type proc (ro,nosuid,nodev)
我没有exportfs
,我在sudo zypper install exportfs
这个 答案可能仍然对 (a) -d
与 -n
选项的讨论以及 (b) 如何 preview xargs
将执行的命令。
据我了解,SUSE 使用 GNU 实用程序,因此您可以 使用 xargs -d'\n'
:
grep -Inrs MY_PATTERN src/ | cut -d: -f1 | xargs -d'\n' sed -i 's/MY_PATTERN/NEW_WORD/g'
xargs -d'\n'
确保 每个输入行 作为一个整体 被视为它自己的参数(保留带空格的文件名的完整性),同时仍然传递尽可能多的参数(通常,全部)一次。
(相比之下,-n 1
会用空格分隔参数,并一次用 1 个参数调用目标命令。)
如果你想预览将执行的命令,使用辅助. bash
命令:
grep -Inrs MY_PATTERN src/ | cut -d: -f1 |
xargs -d'\n' bash -c 'printf "%q " "$@"' _ sed -i 's/MY_PATTERN/NEW_WORD/g'
继续阅读以获得解释。
可选的背景信息。
xargs
有自己的选项,-p
,用于预览要执行的命令 和 提示确认,但预览 没有反映参数边界 的方式直接从 [=113= 调用命令时必须指示它们].
一个简单的例子:
$ echo 'hi, there' | xargs -p -d '\n' printf '%s'
printf %s hi, there ?...
xargs
实际上执行的是printf '%s' 'hi, there'
的等价,但那是没有反映在-p
的提示中。
解决方法:
$ echo 'hi, there' | xargs -d '\n' bash -c 'printf "%q " "$@"' _ printf '%s'
printf %s hi\,\ there
通用辅助 bash
命令 - bash -c 'printf "%q " "$@"' _
,插入到目标命令之前 - 引用 xargs
传递的参数 - on需求,仅在必要时 - 以 shell 需要的方式将每个识别为 单个参数 ,并加入他们有空格。
最终结果是 a shell command 被打印出来,即 equivalent what xargs
将执行 (尽管如您所见,不能保证保留输入的引用样式)。
我建议保持简单:
$ grep -lZ -Irs foo * | xargs -0 sed -i 's/foo/bar/g'
grep -l
只输出匹配的文件名,这正是您在此管道中想要的。 grep -Z
以 NUL
终止每个匹配的文件名,xargs -0
可以选择。这允许嵌入 white-space 的文件名在 grep 和 xargs 之间不受限制地传递。
# show the structure
$ tree
.
└── path
└── to
└── a
└── found
├── file_1
├── file_2
└── file_3
# show the contents
$ grep . path/to/a/found/file_*
path/to/a/found/file_1:a foo bar
path/to/a/found/file_2:a foo bar
path/to/a/found/file_3:a foo bar
# try it out
$ grep -lZ -Irs foo * | xargs -0 ls -l
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_1
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_2
-rw-rw-r-- 1 bishop bishop 10 Feb 13 09:13 path/to/a/found/file_3