演讲者的解决方案可能是最好的,但我仍然是老派,喜欢.sed
您可以sed
在单个-e
参数中提供多个命令,用分号分隔,或者在多个-e
参数中;我更经常使用后者。我还将清理名称find
以删除主要路径。然后你需要决定你是否使用扩展的正则表达式 not,并且你需要在你使用的内容上保持一致。
使用 GNU sed
4.4.2 (©2012),我无法获得\d
识别数字的符号;这里可能有一些愚蠢的东西。
没有扩展的正则表达式(将适用于非 GNU 版本sed
):
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
使用 GNUsed
的“扩展正则表达式”模式 ( -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