我想写一个动态BASH脚本,它将从命令行获取用户输入,并对提供的TSV文件执行标准化。
TSV输入示例:
COL1 COL2 COL3 COL4
YES NOT NAME,EX LOL,OK
Y N NICE,ED LOUD,ONE
YE NO NEED,ER LONE,TWO
作为输入,脚本将采用分隔符、列号(一个或多个)和输入文件,并允许用户将列表中的每个项目的行复制为列字段。
COL1 COL2 COL3 COL4
YES NOT NAME LOL
YES NOT EX OK
Y N NICE LOUD
Y N ED ONE
YE NO NEED LONE
YE NO ER TWO
我尝试了很多不同的组合,例如这个:
#!/bin/bash
# Get user input for the selected columns (starting from 1)
echo "Enter the column numbers to split (separated by spaces):"
read -ra col_nums
# Get user input for the delimiter
echo "Enter the delimiter:"
read delimiter
# Get the input file name
echo "Enter the input file name:"
read input_file
# Get the output file name
echo "Enter the output file name:"
read output_file
# Create a temporary file for storing the modified data
temp_file=$(mktemp)
# Set the field separator to the delimiter
awk -v col_nums="${col_nums[*]}" -v delimiter="$delimiter" '
BEGIN { FS = OFS = "\t"; split(col_nums, cn, " ") }
{
for (i in cn) {
# Split the selected column
split($(cn[i]), a, delimiter)
# Loop through the split array and create the new columns
for (j = 1; j <= length(a); j++) {
# Print the original columns up to the selected column
for (k = 1; k < cn[i]; k++) {
printf("%s%s", $k, OFS)
}
# Print the new column
printf("%s%s", a[j], OFS)
# Print the original columns after the selected column
for (k = cn[i] + 1; k <= NF; k++) {
printf("%s%s", $k, (k == NF ? ORS : OFS))
}
}
}
}' "$input_file" > "$temp_file"
# Rename the temporary file to the output file name
mv "$temp_file" "$output_file"
echo "Done."
然而,在运行这个作为输出后,我得到:
COL1 COL2 COL4 COL4
YES NOT LOL LOL,OK
YES NOT OK LOL,OK
Y N LOUD LOUD,ONE
Y N ONE LOUD,ONE
YE NO LONE LONE,TWO
YE NO TWO LONE,TWO
你能告诉我我做错了什么吗?什么是解决这个问题的最佳方法?如果用一行程序解决这个问题,我也很好,但我的成功率更低。
如果定界符和列号是预先知道的,我就知道如何做到这一点,但对我来说,问题是输出取决于用户输入,并且可以提供多个列作为输入。
2条答案
按热度按时间tkqqtvp11#
使用任何awk:
上面的假设,正如你在评论中所说:
如果指定了两列,则它们具有相同数量的逗号分隔标记。
显然,编写任何您喜欢的shell代码来从用户输入中读取/填充
col_nums
等。我将shell变量
col_nums
从数组更改为标量,因为在该代码中没有理由将其作为数组。jtw3ybtb2#
下面是一个Ruby来实现这一点:
打印此TSV输出:
使用JSON来发送配置(我认为这是不言自明的),并使用shell脚本来填充这一简单的JSON行:
如果你想要一个 table(其中列对齐)与 TSV,在TSV输出的管道中使用
column -t
:图纸:
这里的优点是Ruby版本更好地支持兼容的CSV / TSV输入和输出,包括引用字段,日期和转换。