如何使用find和awk提取部分文件名

时间:2017-02-13 01:25:21

标签: bash ubuntu awk find

我有这个目录结构

sample1__app
sample2__test

我想提取sample1sample2,然后再做进一步的操作,但我仍然坚持这个

find . -type d -maxdepth 1 -mindepth 1 -exec awk -d'__' '{print $0}' {}  \;

1 个答案:

答案 0 :(得分:2)

您的awk命令正在尝试打开文件(在这种情况下为目录)并处理其内容, awk并不热衷在做。

而且,无论如何,$0中的awk整个输入行 - 我怀疑您想要第一个字段,即$1

您真正想要的是处理目录名称本身(而不是其内容),您可以使用以下内容来处理:

find . -maxdepth 1 -mindepth 1 -type d | awk -F'__' '{ sub ("^./", "", $1); print $1 }'

您只需将find的输出通过awk,而不是将目录名称作为输入文件。 sub会从输出中删除前导./,之后您只需打印出该字段。

顺便说一下,您可能需要注意奇怪的边缘情况,例如带有换行符的目录名称。我已经为您的特定数据量身定制了这个答案,它应该适用于更简单的边缘情况(例如文件名中包含空格),但换行符会导致问题。

我个人的观点是,使用换行符,退格键等构建文件名的人是邪恶的,并且应该得到他们得到的一切: - )

但是,如果确实需要处理嵌入式换行符,则可以通过不在find - 到 - awk管道中拆分这些文件名来实现。为此,创建一个脚本,使用引号正确处理一个参数(例如,proc.sh):

#!/usr/bin/env bash
bit="$1"             # Get the argument.
bit="${bit#\./}"     # Remove ./ at start.
bit="${bit%__*}"     # Remove from last __ onward (use %% for first).
echo "[$1] [${bit}]" # Show effect.

然后从find本身调用它(再次引用以确保参数不被拆分):

find . -maxdepth 1 -mindepth 1 -type d -exec ./proc.sh "{}" ';'

运行这是一个包含子目录的目录(XX是嵌入式换行符):

dodgy__extXXwith-newline/
sample1__app/
sample2__test/

将正确处理它(注意" dodgy"文件的多行[...],并且为了便于阅读,输出已经稍微重新格式化):

[./sample2__test]       [sample2]
[./sample1__app]        [sample1]
[./dodgy__ext
with-newline]           [dodgy]