从命令到每个输出行的前缀和后缀字符串


17

我在尝试编写Bash脚本时遇到了问题。当grep输出时,它返回(通常)多行。我想为这些输出行中的每条前缀和后缀一个字符串。

我还想指出,我正在ls加入grep,例如:

ls | grep

2
您不应该解析ls-这是个坏枣。另外,必须grep吗?能否给出一些示例输出?
Sobrique 2015年

1
如果文件名包含换行符,您希望脚本做什么?
Tai Viinikka

Answers:


27

与sed:

ls | grep txt | sed 's/.*/prefix&suffix/'

3
或者说,sed是的超集grepls | sed -n '/txt/s/.*/prefix&suffix/p'ls | sed -n 's/.*txt.*/prefix&suffix/p'
斯特凡Chazelas

@StéphaneChazelas:谢谢您的提示。
赛勒斯

5

sed

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

但是请注意,这会遇到换行文件名问题以及所有各种各样的解析问题,ls这通常是一个坏主意。

与Perl

perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

注意-perl grep可以采用某种模式-类似于grep命令,但是您也可以执行诸如应用文件测试之类的操作。

例如

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

grep默认迭代器内将$_其设置为当前元素值,因此您可以应用sed/设置grep正则表达式样式或基于来执行各种任务$_


在使用sed的第一个示例中,如何在后缀/前缀中包含变量?
SpecialBomb

将引号更改为,然后仅使用em。
Sobrique 2015年

2

在这种情况下,GNU find允许您一次完成所有这些操作,从而消除了管道和潜在的麻烦的解析ls

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

(当然,find这不是随意修改其他命令输出的好方法!)

一些注意事项:

  • -maxdepth 1-name [^.]*化妆名称匹配的工作一样普通ls(或ls .)。您可以使用任何Shell样式的Glob,但是请注意,“ *”将匹配前导“”。的名称与不同bash[^.]*表示没有前导“”的任何内容。
  • MYPATTERN是正确的POSIX ERE(默认类型为Emacs,请参见此处),但是它必须与整个文件名匹配,因此请使用.*thing.*代替代替thing
  • 可能只可以使用-name/ 之一,-regex而不要同时使用两者(例如-regex“ [^。]。MYPATTERN。
  • -printf支持很多东西%n是未经修饰的文件或目录名称

(这可能取决于您的版本find,请查看手册页的“标准符合性”部分)

作为一种可能的替代方案,不需要外部程序,它bash具有compgen扩展glob的功能,等效于ls没有选项的:

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

这将处理带有空格的文件名,包括换行符。compgen -G "*"应该提供与普通输出相同的输出ls(但请注意,ls *这完全是另一回事)。您仍然需要grep,这可能会或可能不会解决问题,但是值得一提。


0

sedfind或受到挑战的解决方案,如果你的前缀/后缀包括正则表达式的关键字符,如果想传递一个环境变量(而不是立即值),xargs+ echo可能更适合这里。

使用环境变量:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

内联:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.