我有两个问题。我有一个文件夹,其中包含包含.txt文件的子文件夹。 txt文件的格式为
{title.of.a.book}.V{4 digit year}.{4 digit issue}.txt
例如
to.kill.a.mockingbird.V1960.0001.txt
我想提取三条信息:
这是我到目前为止所写的内容
for file in $(find /home/user/books -type f -name '*.txt')
do
name=$(echo "$file"|sed -e 's/^\(.*\).V.*txt$/\1/')
volume=$(echo "$file"|sed -e 's/^.*V\(\d{4}\).*$/\1/')
issue=$(echo "$file"|sed -e 's/^.*\(\d{4}\).txt$/\1/')
echo "$name" "$volume" "$issue"
done
.
醇>
我无法决定是先重命名文件(重命名s/./ /g
) - 还是之后重命名$name
。
name变量打印正确,但volume和issue number变量只打印文件名...
答案 0 :(得分:3)
不需要使用sed,bash可以使用param扩展来处理它。
假设您的所有文本文件都使用上述格式:
#!/bin/bash
for file in $(find /home/user/books -type f -name '*.txt'); do
pre=${file%%.txt}
pre=${pre//./ }
name=${pre%% V*}
volume=${pre##* V}
volume=${volume%% *}
issue=${pre##* }
echo "Name: '$name' Volume: '$volume' Issue: '$issue'"
done
答案 1 :(得分:0)
solution speakr可能是最好的,但我还是老了,喜欢sed
。
您可以在单个sed
参数中向-e
提供多个命令,以分号或多个-e
参数分隔;我通常使用后者。我还要从find
清除名称以删除主要路径。然后你需要决定你是否使用了非扩展正则表达式,并且你需要在你使用的内容中保持一致。
使用GNU sed
4.4.2(©2012),我无法使用\d
表示法来识别数字;这里可能有些蠢。
没有扩展的正则表达式(适用于非sed
的GNU版本):
for file in $(find /home/user/books -type f -name '*.txt')
do
base=$(basename $file .txt)
name=$( echo "$base" | sed -e 's/^\(.*\).V.*$/\1/' -e 's/\./ /g') # replace dots
volume=$(echo "$base" | sed -e 's/^.*V\([0-9]\{4\}\).*$/\1/')
issue=$( echo "$base" | sed -e 's/^.*\([0-9]\{4\}\)$/\1/')
echo "$name" "$volume" "$issue"
done
示例书的输出:
to kill a mockingbird 1960 0001
使用GNU sed
的'扩展正则表达式'模式(-r
):
for file in $(find /home/user/books -type f -name '*.txt')
do
base=$(basename $file .txt)
name=$( echo "$base" | sed -r -e 's/^(.*).V.*$/\1/' -e 's/\./ /g') # replace dots
volume=$(echo "$base" | sed -r -e 's/^.*V([0-9]{4}).*$/\1/')
issue=$( echo "$base" | sed -r -e 's/^.*([0-9]{4})$/\1/')
echo "$name" "$volume" "$issue"
done
使用\d
表示法(输出错误):
for file in $(find /home/user/books -type f -name '*.txt')
do
base=$(basename $file .txt)
name=$( echo "$base" | sed -r -e 's/^(.*).V.*$/\1/' -e 's/\./ /g') # replace dots
volume=$(echo "$base" | sed -r -e 's/^.*V(\d{4}).*$/\1/')
issue=$( echo "$base" | sed -r -e 's/^.*(\d{4})$/\1/')
echo "$name" "$volume" "$issue"
done
输出:
to kill a mockingbird to.kill.a.mockingbird.V1960.0001 to.kill.a.mockingbird.V1960.0001