使用 sed 解析 ls 输出以获取具有特定名称的文件的文件位置

使用 sed 解析 ls 输出以获取具有特定名称的文件的文件位置

首先,我知道这种方式并不正确,正如人们经常提到的那样为什么我不应该解析 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'.我想实现这样的目标:

  1. sed(或awk?)解析每一行并搜索以以下开头的行'Do'
  2. 如果存在匹配项,则移至上一行并搜索 。 (这是相对路径的指示符),如果没有匹配则跳转到之前的行等等
  3. 将行打印为相对路径:.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
  }'

相关内容