谦逊的书包 · 土耳其“枪鱼”入水|无人艇|土耳其|电子战_ ...· 7 月前 · |
性感的毛豆 · Grad-CAM与T-SNE ...· 1 年前 · |
苦恼的洋葱 · js fetch 同步请求 - ...· 1 年前 · |
憨厚的皮蛋 · React-native 关于 ...· 1 年前 · |
数据文件- data.txt:
ABC "I am ABC" 35 DESC
DEF "I am not ABC" 42 DESC
cat data.txt | awk '{print $2}'
将产生"I“而不是被引号的字符串。
如何使awk忽略引号中的空格,并认为它是一个单独的令牌?
是的,这可以在awk中很好地完成。很容易获得所有的字段,而不需要任何严重的黑客攻击。
(此示例在 The One True Awk 和gawk中都有效。)
{
split($0, a, "\"")
$2 = a[2]
$3 = $(NF - 1)
$4 = $NF
print "and the fields are ", $1, "+", $2, "+", $3, "+", $4
}
我整理了一个函数,它将$0重新拆分到一个名为B的数组中。双引号之间的空格不起到字段分隔符的作用。适用于任意数量的字段,可以是带引号的和不带引号的字段的混合。如下所示:
#!/usr/bin/gawk -f
# Resplit $0 into array B. Spaces between double quotes are not separators.
# Single quotes not handled. No escaping of double quotes.
function resplit( a, l, i, j, b, k, BNF) # all are local variables
l=split($0, a, "\"")
BNF=0
delete B
for (i=1;i<=l;++i)
if (i % 2)
k=split(a[i], b)
for (j=1;j<=k;++j)
B[++BNF] = b[j]
B[++BNF] = "\""a[i]"\""
resplit()
for (i=1;i<=length(B);++i)
print i ": " B[i]
}
希望能有所帮助。
此问题的最高答案仅适用于具有单引号字段的行。当我发现这个问题时,我需要一些可以处理任意数量的引用字段的东西。
最终我遇到了
an answer by Wintermute in another thread
,他为这个问题提供了一个很好的通用解决方案。我刚刚修改了它,删除了引号。请注意,在运行以下程序时,您需要使用
-F\"
调用awk。
BEGIN { OFS = "" } {
for (i = 1; i <= NF; i += 2) {
gsub(/[ \t]+/, ",", $i)
print
}
这是通过观察数组中的每个其他元素都位于引号内的方式来实现的,当您使用"-character“分隔时,它会用逗号替换分隔不在引号中的元素的空格。
然后,您可以轻松地链接awk的另一个实例来执行所需的任何处理(只需再次使用字段分隔符开关
-F,
)。
请注意,如果第一个字段被引用,这可能会中断-我还没有测试它。如果是这样的话,如果行的第一个字符是“,那么通过添加一个If语句从2开始,而不是从1开始,应该很容易修复。
这是我最终得到的一些东西,它对我的项目更通用。注意,它不使用awk。
someText="ABC \"I am ABC\" 35 DESC '1 23' testing 456"
putItemsInLines() {
local items=""
local firstItem="true"
while test $# -gt 0; do
if [ "$firstItem" == "true" ]; then
items="$1"
firstItem="false"
items="$items
shift
echo "$items"
count=0
while read -r valueLine; do
echo "$count: $valueLine"
count=$(( $count + 1 ))
done <<< "$(eval putItemsInLines $someText)"
以下哪项输出:
0: ABC
1: I am ABC
2: 35
3: DESC
4: 1 23
5: testing
6: 456
性感的毛豆 · Grad-CAM与T-SNE 可视化代码实现 - 知乎 1 年前 |