首先,我知道这种方式并不正确,正如人们经常提到的那样为什么我不应该解析 ls 的输出,但它是我大学项目的一部分(所以我可以同时使用 sed 和 awk)。
我必须找到名称以给定字符串开头的文件。我开始使用以下命令列出当前目录ls
:
ls -LR1
这给了我示例输出:
.:
bin
etc
games
include
lib
man
sbin
share
src
./bin:
apt
gnome-help
highlight
mint-sha256sum
pastebin
search
szukaj
yelp
./etc:
./games:
./include:
./lib:
python2.7
python3.5
./lib/python2.7:
dist-packages
site-packages
./lib/python2.7/dist-packages:
./lib/python2.7/site-packages:
./lib/python3.5:
dist-packages
./lib/python3.5/dist-packages:
./man:
./sbin:
./share:
ca-certificates
emacs
fonts
man
sgml
xml
./share/ca-certificates:
./share/emacs:
site-lisp
./share/emacs/site-lisp:
./share/fonts:
./share/man:
./share/sgml:
declaration
dtd
entities
misc
stylesheet
./share/sgml/declaration:
./share/sgml/dtd:
./share/sgml/entities:
./share/sgml/misc:
./share/sgml/stylesheet:
./share/xml:
declaration
entities
misc
schema
./share/xml/declaration:
./share/xml/entities:
./share/xml/misc:
./share/xml/schema:
./src:
现在我想使用sed
或可能awk
获取名称以给定字符串开头的文件,比如说'Do'
.我想实现这样的目标:
sed
(或awk
?)解析每一行并搜索以以下开头的行'Do'
- 如果存在匹配项,则移至上一行并搜索 。 (这是相对路径的指示符),如果没有匹配则跳转到之前的行等等
- 将行打印为相对路径:
.path/filename
甚至有可能实现吗?感谢您的帮助!
答案1
作为示例,让我们考虑以下文件:
$ ls -LR1
.:
a
./a:
b
./a/b:
bad
Do_good
现在,让我们找到您想要的文件:
$ ls -LR1 | awk '/^\.\//{sub(/:$/, "/", $0); dir=$0} /^Do/{print dir $0}'
./a/b/Do_good
怎么运行的:
/^\.\//{sub(/:$/, "/", $0); dir=$0}
每次我们找到以 开头的行时,我们都会用a
./
替换查找内容并更新变量:
/
dir
/^Do/{print dir $0}
每当我们找到以 开头的行时,我们都会打印该行后面的
Do
变量。dir
局限性:如您所知, 的输出ls
旨在是人类可读的,并且解析它是不可靠的。此代码仅用于演示awk
.它不应该用于任何严重的事情。
首选方法 -- 1
作为通配符指出,find
是完成此任务的正确工具:
$ find . -name 'Do*'
./a/b/Do_good
首选方法 -- 2(需要 bash)
在 bash 中,如善行难陀指出,可以使用 globstar 功能递归搜索文件:
shopt -s globstar nullglob
printf '%s\n' **/Do*
答案2
使用sed
,您可以使用保留空间来存储最后看到的目录的路径:
sed -n '
/^\..*:$/{
h;d
}
/^Do/{
G
s|\(.*\)\n\(.*\):|\2/\1|p
}'