【问题标题】:Tiny utility decoding base64-encoded file names微型实用程序解码 base64 编码的文件名
【发布时间】:2014-07-03 06:31:16
【问题描述】:

为了方便和快速地调试我的R 代码,我决定创建一个很小的AWK 脚本。它所要做的就是解码特定目录中所有 base64 编码的文件名 (.RData)。我已经尽力了两次。以下是我到目前为止的结果。任何帮助将不胜感激!

第一次尝试AWK脚本嵌入shell命令中:

ls -1 ../cache/SourceForge | awk 'BEGIN {FS="."; print ""} {printf("%s", $1); printf("%s", " -> "); print $1 | "base64 -d -"; print ""} END {print ""}'

产生的输出接近所需的,但是,这种单行打印不是将每个解码的文件名与原始编码的文件名打印在同一行上处理结束时的所有解码名称,根本没有输出分隔符:

cHJqTGljZW5zZQ== ->
cHViUm9hZG1hcA== ->
dG90YWxEZXZz ->
dG90YWxQcm9qZWN0cw== ->
QWxsUHJvamVjdHM= ->
Y29udHJpYlBlb3BsZQ== ->
Y29udHJpYlByb2Nlc3M= ->
ZG1Qcm9jZXNz ->
ZGV2TGlua3M= ->
ZGV2U3VwcG9ydA== ->

prjLicensepubRoadmaptotalDevstotalProjectsAllProjectscontribPeoplecontribProcessdmProcessdevLinksdevSupport

第二次尝试是下面的独立AWK脚本:

#!/usr/bin/gawk -f

BEGIN {FS="."; print ""; files = "ls -1 ../cache/SourceForge"}
{
  decode = "base64 -d -";
  printf("%s", $1); printf("%s", " -> "); print $1 | decode; print ""
}
END {print ""}

然而,这个脚本的行为令人惊讶的,首先,它等待输入,其次,在收到EOF (Ctrl-D) 时,它不会'不产生任何输出。

【问题讨论】:

  • 我不在乎我的评分,只是好奇为什么要投反对票。需要解释一下吗?
  • 不是我,但我想知道为什么你不只是问“这打印出foo bar 8。为什么不是foo 4 bar 4printf "foo\nbar\n" | awk '{ print $1; print $1 | "wc -c"; }'
  • @thatotherguy:感谢您的评论!虽然有些人更喜欢简洁,但其他人更喜欢理解上下文,它通常包含基本细节,因此很重要。我相信每个人都是独一无二的,因此,在提问、提供信息等方面都有她/他自己的风格。我不认为个人的做事风格应该被视为没有价值。
  • 示例应该是small, self contained and correct。要求人们有一个 sourceforge 缓存目录来重现问题不是个人风格的问题。
  • @thatotherguy:我明白了。谢谢你表达你的观点。正如我所说,这也是个人对围绕核心信息的上下文数量的容忍度(和价值)的问题。一方面,上下文是一种干扰,另一方面 - 它是更好地理解主题的宝贵元素。再次感谢并致以最良好的祝愿!

标签: bash awk scripting base64 text-parsing


【解决方案1】:

主要是 bash 解决方案:

for f in ../cache/SourceForge/*; do
  base=$(basename $f .RData)
  echo "$base => $(base64 -d <<<$base)"
done

或者,使用更多 bash:

for f in ../cache/SourceForge/*; do
  f=${f##*/}; f=${f%%.*}
  echo "$f => $(base64 -d <<<$f)"
done

在这两种情况下,您都可以使用../cache/SourceForge/*.RData 来更具体地确定您想要的文件名。在第二个中,使用f=${f%.*} 将导致仅删除一个扩展名。或者f=${f%.RData} 将导致仅删除.RData 扩展名。但它在特定应用程序中可能几乎没有什么区别。

【讨论】:

  • 太棒了!非常感谢!虽然我更喜欢AWK 解决方案,但这也非常好(且实用)。我很高兴有机会学习更多Unix shell 编程! :-) 由于其他答案(截至目前)没有提供完整和正确的解决方案,我很乐意接受你的答案!
【解决方案2】:
while read
do
  base64 -d <<< $REPLY
  echo
done < infile.txt

结果

项目许可证 pub路线图 总开发 项目总数 所有项目 贡献人 贡献进程 dmProcess 开发链接 开发支持

【讨论】:

  • 感谢您的回答!我不想处理额外的文件 - 我想使用管道将ls -1 &lt;dir&gt; 输出直接发送到处理部分(最好在实用程序的主体内,正如我在第二次尝试中尝试的那样)。此外,您的代码似乎没有处理(丢弃)文件扩展名 - 这就是我尝试使用 AWK 的原因(除了更熟悉它并且它看起来更好恕我直言)。您能否建议更改您的代码以处理上述要求?
  • 他的文件中似乎有多个按句点分隔的字段。所以你需要在循环中使用while IFS=. read file extra 然后printf "%s " $file; base64 -d &lt;&lt;&lt;$file; echo 或类似的东西来获得正确的输出。
【解决方案3】:

您需要在每行之间关闭您正在写入的进程,或者 awk 将所有打印的行发送到同一个进程(我猜它只会在完成时打印输出)。将close("base64 -d -") 添加到该操作块的末尾(完全相同的命令字符串)。例如:

ls | awk -F. '{ printf("%25s -> ", $1); print $1 | "base64 -d -"; close("base64 -d -"); print "" }'

您的第二个 sn-p 没有运行 ls 命令。它只是将它分配给一个变量并且什么都不做。您需要将输出从ls 传送到awk -f &lt;yourscript&gt;./your-script.awk 或类似的方法才能使其工作。 (这就是为什么它在等待你的输入,你还没有给它。)

要从 awk 实际运行 ls,您需要使用 getline

类似awk 'BEGIN {while ( ("ls -1" | getline) &gt; 0 ) {print}}'

【讨论】:

  • 你在第二个sn-p中试过了吗?我正在测试第一个,但前提是相同的。我应该提一下,在这里进行测试时,我从 base64 收到了关于错误输入的错误(尽管我也得到了正确的解码输出)。
  • 我没有清楚你的数据是我自己测试的。我认为这只是我的 base64 二进制文件的一个怪癖以及在 awk 中使用管道的方式。我只是想以防万一。我对您的第二个 sn-p 和 ls 命令的编辑是该 sn-p 对您根本不起作用的原因。
  • @AleksandrBlekh:您需要在管道后立即关闭,即在第一次尝试时使用:...; print $1 | "base64 -d -"; close("base64 -d -"); ...;
  • @AleksandrBlekh:这是一个在这里工作的代码块:{ printf("%25s -&gt; ", $1); print $1 | "base64 -d -"; close("base64 -d -"); print "" }
  • @AleksandrBlekh:Etan 已经提出建议,所以我在他的回答中添加了代码 sn-p。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-27
  • 2015-05-17
  • 2012-01-07
  • 2021-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多