我有一堆Wordpress文件的垃圾转储,我正在尝试将它们全部转换为Markdown。
我写的脚本是:
htmlDocs=($(find . -print | grep -i '.*[.]html'))
for html in "${htmlDocs[@]}"
do
P_MD=${html}.markdown
echo "${html} \> ${P_MD}"
pandoc --ignore-args -r html -w markdown < "${html}" | awk 'NR > 130' | sed '/<div class="site-info">/,$d' > "${P_MD}"
done
据我所知,第一行应该是在所有子目录中创建所有html
文件的数组,然后for循环有一行来创建一个具有Markdown名称的变量(后跟调试回显),然后是实际的pandoc
命令进行转换。
一次一个,这个命令有效。
然而,当我尝试执行它时,OSX给了我:
$ ./pandoc_convert.command
./pandoc_convert.command: line 1: : No such file or directory
./pandoc_convert.command: line 1: : No such file or directory
O_0
帮助?
答案 0 :(得分:2)
脚本失败的原因可能有很多,因为创建数组的方式不正确:
htmlDocs=($(find . -print | grep -i '.*[.]html'))
数组的格式为:NAME=(VALUE1 VALUE2 ... )
,其中NAME
是变量的名称,VALUE1
,VALUE2
,其余是以字符分隔的字段存在于$IFS
(输入字段分隔符)变量中。假设您找到带空格的文件名。然后表达式将在数组中创建单独的项目。
另一个问题是表达式不处理globbing,即基于*
等特殊字符的shell扩展生成文件名:
mkdir dir.html
touch \ *.html
touch a\ b\ c.html
a=($(find . -print | grep -i '.*[.]html'))
for html in "${a[@]}"; do echo ">>>${html}<<<"; done
输出
>>>./a<<<
>>>b<<<
>>>c.html<<<
>>>./<<<
>>>a b c.html<<<
>>>dir.html<<<
>>> *.html<<<
>>>./dir.html<<<
我知道有两种方法可以解决此问题:1)暂时禁用通配,2)使用mapfile
命令。
禁用全局
# Disable globbing, remember current -f flag value
[[ "$-" == *f* ]] || globbing_disabled=1
set -f
IFS=$'\n' a=($(find . -print | grep -i '.*[.]html'))
for html in "${a[@]}"; do echo ">>>${html}<<<"; done
# Restore globbing
test -n "$globbing_disabled" && set +f
输出
>>>./ .html<<<
>>>./a b c.html<<<
>>>./ *.html<<<
>>>./dir.html<<<
使用mapfile
在Bash 4中引入了mapfile
。该命令将标准输入中的行读入索引数组:
mapfile -t a < <(find . -print | grep -i '.*[.]html')
for html in "${a[@]}"; do echo ">>>${html}<<<"; done
find
选项
find
命令选择所有类型的节点,包括目录。您应该使用-type
选项,例如文件-type f
。
如果要使用正则表达式过滤结果集,请使用-regex
选项,或使用-iregex
进行不区分大小写的匹配:
mapfile -t a < <(find . -type f -iregex .*\.html$)
for html in "${a[@]}"; do echo ">>>${html}<<<"; done
输出
>>>./ .html<<<
>>>./a b c.html<<<
>>>./ *.html<<<
echo
与printf
最后,don't use echo
in new software。请改用printf
:
mapfile -t a < <(find . -type f -iregex .*\.html$)
for html in "${a[@]}"; do printf '>>>%s<<<\n' "$html"; done
替代方法
但是,我宁愿使用read
:
find . -type f -iregex .*\.html$ | while read line
do
printf '>>>%s<<<\n' "$line"
done
在此示例中,read
命令从标准输入中读取一行,并将值存储到line
变量中。
虽然我喜欢mapfile
功能,但我发现管道的代码更清晰。
答案 1 :(得分:1)
尝试添加bash shebang并设置IFS来处理文件夹和文件名中的空格:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
htmlDocs=($(find . -print | grep -i '.*[.]html'))
for html in "${htmlDocs[@]}"
do
P_MD=${html}.markdown
echo "${html} \> ${P_MD}"
pandoc --ignore-args -r html -w markdown < "${html}" | awk 'NR > 130' | sed '/<div class="site-info">/,$d' > "${P_MD}"
done
IFS=$SAVEIFS