我有一个文件记录了几个目录的结构。我正在尝试分别打印每个目录的文本。我的输入文件如下所示:
$ cat file.txt
/bin:
file_1
file_2
file_3
/sbin:
file_a
file_b
file_c
/usr/local/bin:
doc_a
doc_b
doc_c
我要做的是根据用户选择打印文件的特定部分:
#!/bin/bash
PS3=$'\nMake a selection '
select dir in $(grep ':' file.txt;) do
case $REPLY in
[0-9]) echo $dir
# Need something here. Maybe a pcregrep regex?
# pcregrep '(<= $dir)*(some_fancy_regex)' file.txt
break;;
esac
done
向用户呈现菜单选项:
1) /bin:
2) /sbin:
3) /usr/local/bin:
Make a selection
假设用户选择 2。目前,这只是在屏幕上打印所选目录。我想显示目录及其包含的文件。
/sbin:
file_a
file_b
file_c
根据我的阅读,pcre 正则表达式似乎可以在这里工作。我几乎不了解非 pcre 风格的正则表达式。我正试图让我的大脑围绕积极和消极的前瞻性和后瞻性思考,但我真的不知道我在做什么。如果有人能帮我解决这个问题,我将不胜感激。
- 所有目录都以
/
开头并以:
结尾 - 每个目录下列出的文件名可能包含:
[a-z]
,[A-Z]
,[0-9]
- 文字字符
.
_
-
[
- 所有目录/文件结构都以空行结尾
最佳答案
它可以完全在 bash 4 中一次完成,无需使用任何外部工具。这是解决这个问题的脚本:
#!/bin/bash
# declare an associative array
declare -A dirs=()
# loop thru all lines and populate our associate array
# with dir as key and \n separated file names as value
while read -r; do
[[ -z $REPLY ]] && continue
if [[ $REPLY == *: ]]; then
d="$REPLY"
else
dirs["$d"]+=$'\n'"$REPLY"
fi
done < file.txt
# present a menu to customer and print selected dir name with file names
select dir in "${!dirs[@]}"; do
if [[ -n $dir ]]; then
printf '%s%s\n' "$dir" "${dirs[$dir]}"
break
fi
done
输出:
1) /usr/local/bin:
2) /bin:
3) /sbin:
#? 1
/usr/local/bin:
doc_a
doc_b
doc_c
还有这个:
1) /usr/local/bin:
2) /bin:
3) /sbin:
#? 3
/sbin:
file_a
file_b
file_c
关于regex - 提取文件中两个目录条目之间的所有文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42871682/