awk - awk 解决方案,用于按列搜索任何字符的第一个实例(但一个!)
问题描述
我有一个(先前排序的)文本文件,由破折号-
或单个字母字符组成。我非常感谢任何有助于更好地理解正确的 awk 语法以遍历文本文件的每一列,如果存在非破折号字符,则仅保留每行中的第一个非破折号字符,否则保留该破折号字符如果不存在字母字符。任何一种情况下的结果都是单行文本。文件总是以这样一种方式格式化,即每行都有相同的列数,并且总是首选第一个非破折号字符,不管“较低”行中是否存在其他字母字符。
两个例子来澄清:给定这个文本文件:
# printf 't---k-\ncha---\n--nn--\n--ab-s\n'
t---k-
cha---
--nn--
--ab-s
该程序将从第一列开始,并且因为第一个字符不是破折号,它会保留一个t
. 然后我们将继续到下一列,其中第一行信息是一个破折号,因此前进到第二行,其中h
选择了 an。然后您将前进到第三列,并且必须移动到第三行以选择n
字符等。要报告的预期字符串是:
thanks
.
在第二个示例中,我们有一个非常相似的文本排列,但有一个例外:
#printf 't-----\ncha---\n--nn--\n--ab-s\n'
t-----
cha---
--nn--
--ab-s
请注意,在第二个示例中,第四列中没有字母字符。因为不存在这样的字符,我们将在该位置返回一个破折号。因此,预期的输出将是:
than-s
这篇文章重点介绍了一种类似于我想要实现的 pandas 方法,这篇文章同样通过 numpy 提供了一个解决方案,但我相信它们都需要适用于整数的函数,而我有一个由字母字符组成的数据集。这篇文章类似地解释了一种使用 awk 以列方式应用函数的方法,这更接近我所追求的,就像其他awk 文章一样。在我看来,我所追求的 awk 方法同样需要我声明一个按列的方法,我认为它在函数的开头说明为:
awk '{for (i=1;i<=NF;i++){
...我被困的地方是试图识别函数的下一个参数,我认为我在使用某种类型的 if/else 语句。这是我希望得到进一步澄清的部分。
也许解决方案不需要通过awk 完成——我当然愿意接受其他依赖于任何语言的策略,所以如果 Python 或 Perl 或其他一些策略显然是更合适的语言,谢谢你的教育。
感谢您的考虑
解决方案
在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ cat tst.awk
{
numChars = length($0)
for (i=1; i<=numChars; i++) {
if ( chars[i] ~ /^-?$/ ) {
chars[i] = substr($0,i,1)
}
}
}
END {
for (i=1; i<=numChars; i++) {
printf "%s%s", chars[i], (i<numChars ? "" : ORS)
}
}
$ awk -f tst.awk file1
thanks
$ awk -f tst.awk file2
than-s
推荐阅读
- python - 不通过 Docker CLI 手动调用时,Docker 容器中的 Python 脚本运行良好
- java - Eclipse 数据源资源管理器 - 无法创建视图:org.eclipse.datatools.connectivity.DataSourceExplorerNavigator (java)
- python - 使用带有 sample_weight 的 numpy 从头开始计算岭回归
- html - 尝试使用 CSS 和弹性框将段落移动到按钮下的下一行
- node.js - 通过 cron 作业启动交互式 CLI 应用程序
- sql - 在 Oracle SQL Query 中转换 Text 中的一系列 Number 值
- youtube-data-api - 评论列表片段中未返回 videoId
- google-cloud-monitoring - 在 Cloud 任务队列中有超过一定数量的任务且重试值 > 0 时触发 GCP 监控中的警报
- azure-log-analytics - Azure Log Analytics:无法解析表或列或标量表达式
- generics - 移出泛型类型的共享引用