bash - AWK:像输入文件一样保持字段间距

标签 bash perl awk

我在下面的测试文件中模拟我的问题:

# cat out 
2014-01-10 18:23:25          0 Andy/ADPTER/
2014-01-10 18:23:36        503 Sandy/ADPTER/ACCOUNTTYPE MAP.csv
2014-01-10 18:23:38        516 John/ADPTER/CITY MAP.csv
2014-01-10 18:23:38        398 Wendy/ADPTER/COUNTRY MAP.csv
2014-01-10 18:23:38      11117 Andy/ADPTER/CURRENCY MAP.csv
2014-01-10 18:23:38        260 Sandy/ADPTER/GENDER MAP.csv
2014-01-10 18:23:39        466 John/ADPTER/STATE MAP.csv
2014-01-10 18:23:40        373 Jim/ADPTER/UNITS MAP.csv

这是我的 Bash 变量:

# echo $bucket
bucket_name

因此,在上面的文件中,我希望 Bash 变量值作为第 4 个字段的前缀。

这是我想要的输出:

2014-01-10 18:23:25          0 bucket_name/Andy/ADPTER/
2014-01-10 18:23:36        503 bucket_name/Sandy/ADPTER/ACCOUNTTYPE MAP.csv
2014-01-10 18:23:38        516 bucket_name/John/ADPTER/CITY MAP.csv
2014-01-10 18:23:38        398 bucket_name/Wendy/ADPTER/COUNTRY MAP.csv
2014-01-10 18:23:38      11117 bucket_name/Andy/ADPTER/CURRENCY MAP.csv
2014-01-10 18:23:38        260 bucket_name/Sandy/ADPTER/GENDER MAP.csv
2014-01-10 18:23:39        466 bucket_name/John/ADPTER/STATE MAP.csv
2014-01-10 18:23:40        373 bucket_name/Jim/ADPTER/UNITS MAP.csv

这是我试过的:

# awk -v var=$bucket '{$4=var"/"$4; print}' out 
2014-01-10 18:23:25 0 bucket_name/Andy/ADPTER/
2014-01-10 18:23:36 503 bucket_name/Sandy/ADPTER/ACCOUNTTYPE MAP.csv
2014-01-10 18:23:38 516 bucket_name/John/ADPTER/CITY MAP.csv
2014-01-10 18:23:38 398 bucket_name/Wendy/ADPTER/COUNTRY MAP.csv
2014-01-10 18:23:38 11117 bucket_name/Andy/ADPTER/CURRENCY MAP.csv
2014-01-10 18:23:38 260 bucket_name/Sandy/ADPTER/GENDER MAP.csv
2014-01-10 18:23:39 466 bucket_name/John/ADPTER/STATE MAP.csv
2014-01-10 18:23:40 373 bucket_name/Jim/ADPTER/UNITS MAP.csv

问题:

我的 awk 命令可以满足我的需要,但是,它弄乱了外场间距(分隔符 ??)。我的意图是只是bucket_name/作为第4个字段的前缀,并保持输入文件具有的任何间距方案(包括右/左对齐字段)。

这是我的另一个尝试:

# awk -v var=$bucket 'BEGIN{OFS="\t"}{$4=var"/"$4; print}' out 
2014-01-10  18:23:25    0   bucket_name/Andy/ADPTER/
2014-01-10  18:23:36    503 bucket_name/Sandy/ADPTER/ACCOUNTTYPE    MAP.csv
2014-01-10  18:23:38    516 bucket_name/John/ADPTER/CITY    MAP.csv
2014-01-10  18:23:38    398 bucket_name/Wendy/ADPTER/COUNTRY    MAP.csv
2014-01-10  18:23:38    11117   bucket_name/Andy/ADPTER/CURRENCY    MAP.csv
2014-01-10  18:23:38    260 bucket_name/Sandy/ADPTER/GENDER MAP.csv
2014-01-10  18:23:39    466 bucket_name/John/ADPTER/STATE   MAP.csv
2014-01-10  18:23:40    373 bucket_name/Jim/ADPTER/UNITS    MAP.csv

但这也无济于事。

谢谢。

最佳答案

您在 OP 中标记了 Perl,因此有一个 Perl 解决方案:

perl -pe'BEGIN{$var=shift}s,(?:.*?\s+){3}\K,$var/,' "$bucket" out

它在技术上与 solution 的解决方案相同使用 sed 但好处是它避免了转义问题。 Shell 变量 $bucket 可以包含任何内容。

关于bash - AWK:像输入文件一样保持字段间距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29211473/

相关文章:

bash - {awk} 如何读取一行并将 $ 与其下一行/上一行进行比较?

awk - 在 awk 中使用通配符

linux - 计算字数并指定行数

python - optparse 和 bash tab 补全的奇怪行为

objective-c - 从 Objective-C 运行 shell 脚本

linux - Perl 中不区分大小写的 GREP

bash - show-all-if-ambiguous vs show-all-if-unmodified?

mysql - 为什么在向数据库中插入数据时 `state` 不比 `my` 快?

python - 我可以在 Perl 正则表达式中使用命名组来获取哈希结果吗?

regex - 过滤 CSV 文件中的数据