使用 awk 或 python 将字符串的特定索引大写
Capitalize specific indices of string using awk or python
我有一个输入文件,其中每行包含 99 个小写字母,
bccdddcdccddddddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbcbaabbbccbb
bccdddcdcddddcddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbcbaabbbccbb
bccdddcdcddddccdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbccacbbbccbb
bccdddcdccdddccdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbccaaabbccbb
我有一个职位列表,例如p = [10, 14, 89, 99]
。
我想将输入文件中这些位置的字母大写。
期望的输出:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbccbbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
我正在使用这个 awk 命令:
awk -vFS= -vOFS= '{=toupper()}1' input > output
但我不确定如何在所有位置上循环。
您可以使用带有 .upper()
和 enumerate()
的生成器表达式来仅大写指定的索引:
p = [10, 14, 89, 99] # or use set([10, 14, 89, 99]) for faster lookup
with open('in.txt') as file:
for line in file:
line = line.rstrip()
result = ''.join(c.upper() if i + 1 in p else c for i, c in enumerate(line))
print(result)
这输出:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
一个awk
想法:
awk -v p="10,14,89,99" '
BEGIN { split(p,arr,",") }
{ for (i in arr)
[=10=]=substr([=10=],1,arr[i]-1) toupper(substr([=10=],arr[i],1)) substr([=10=],arr[i]+1)
print
}
' input
这会生成:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
我将利用 GNU AWK
来完成此任务,让 file.txt
内容成为
bccdddcdccddddddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbcbaabbbccbb
bccdddcdcddddcddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbcbaabbbccbb
bccdddcdcddddccdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbccacbbbccbb
bccdddcdccdddccdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbccaaabbccbb
然后
awk 'BEGIN{FPAT=".";OFS="";arr[10];arr[14];arr[89];arr[99]}{for(i in arr){$i=toupper($i)};print}' file.txt
给出输出
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
解释:我使用 FPAT
通知 GNU AWK
字段是任何单个字符并且字段分隔符是空字符串然后我提到数组 arr
的键而不关心值,因为我将只使用键。对于每一行,我遍历所述数组的键并将 tuupper 应用于这些位置,然后我 print
line.
(在 GNU Awk 5.0.1 中测试)
这是使用 GNU awk
的 FIELDWIDTHS
选项的 awk
解决方案。仅使用显示的示例编写和测试。
awk -v FIELDWIDTHS="9 1 3 1 74 1 9 1" -v OFS="" '
function toUppeR(value){
$value=toupper($value)
}
{
for(i=2;i<=8;i+=2){
toUppeR(i)
}
}
1
' Input_file
解释: 简单的解释就是,使用 GNU awk
的 FIELDWIDTHS
选项我们可以定义字段的宽度(因此在给定的示例中我们需要将 10, 14, 89, 99
位置的字母大写,因此我将字段设置为抓住第 10 个位置(9 1 ) 赶上第14位(9 1 3 1), 赶上第89位(9 1 3 1 74 1) 等等......你可以清楚地看到它很容易在这里按位置捕获字段,尽管它可以用 OFS
(输出字段分隔符)的东西,但这至少不适用于您显示的示例。
我有一个输入文件,其中每行包含 99 个小写字母,
bccdddcdccddddddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbcbaabbbccbb
bccdddcdcddddcddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbcbaabbbccbb
bccdddcdcddddccdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbccacbbbccbb
bccdddcdccdddccdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbccaaabbccbb
我有一个职位列表,例如p = [10, 14, 89, 99]
。
我想将输入文件中这些位置的字母大写。
期望的输出:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbccbbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
我正在使用这个 awk 命令:
awk -vFS= -vOFS= '{=toupper()}1' input > output
但我不确定如何在所有位置上循环。
您可以使用带有 .upper()
和 enumerate()
的生成器表达式来仅大写指定的索引:
p = [10, 14, 89, 99] # or use set([10, 14, 89, 99]) for faster lookup
with open('in.txt') as file:
for line in file:
line = line.rstrip()
result = ''.join(c.upper() if i + 1 in p else c for i, c in enumerate(line))
print(result)
这输出:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
一个awk
想法:
awk -v p="10,14,89,99" '
BEGIN { split(p,arr,",") }
{ for (i in arr)
[=10=]=substr([=10=],1,arr[i]-1) toupper(substr([=10=],arr[i],1)) substr([=10=],arr[i]+1)
print
}
' input
这会生成:
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
我将利用 GNU AWK
来完成此任务,让 file.txt
内容成为
bccdddcdccddddddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbcbaabbbccbb
bccdddcdcddddcddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbcbaabbbccbb
bccdddcdcddddccdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbccacbbbccbb
bccdddcdccdddccdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbccaaabbccbb
然后
awk 'BEGIN{FPAT=".";OFS="";arr[10];arr[14];arr[89];arr[99]}{for(i in arr){$i=toupper($i)};print}' file.txt
给出输出
bccdddcdcCdddDddabcdabcabdbacbdcaaccbbcabacbccabcacbcdcccbdbacdcbbcbcbcccacadaaccababadbCbaabbbccbB
bccdddcdcDdddCddabcdabcabdbacbddaacdbbcabacbcdbbcacbcccccbdbacdbbbcbcbacbacacaacccbabadbCbaabbbccbB
bccdddcdcDdddCcdabcdabcabdbacbddaaddbbcabacbcdbbcacbcccccbdbacdbbbcbcbaccacadaaccbbabadbCcacbbbccbB
bccdddcdcCdddCcdabcdabcdbdbacbdcaaddcbcabacbccabcacbcdcccbdbacdbbbcbcbbccacadaaccbbabadbCcaaabbccbB
解释:我使用 FPAT
通知 GNU AWK
字段是任何单个字符并且字段分隔符是空字符串然后我提到数组 arr
的键而不关心值,因为我将只使用键。对于每一行,我遍历所述数组的键并将 tuupper 应用于这些位置,然后我 print
line.
(在 GNU Awk 5.0.1 中测试)
这是使用 GNU awk
的 FIELDWIDTHS
选项的 awk
解决方案。仅使用显示的示例编写和测试。
awk -v FIELDWIDTHS="9 1 3 1 74 1 9 1" -v OFS="" '
function toUppeR(value){
$value=toupper($value)
}
{
for(i=2;i<=8;i+=2){
toUppeR(i)
}
}
1
' Input_file
解释: 简单的解释就是,使用 GNU awk
的 FIELDWIDTHS
选项我们可以定义字段的宽度(因此在给定的示例中我们需要将 10, 14, 89, 99
位置的字母大写,因此我将字段设置为抓住第 10 个位置(9 1 ) 赶上第14位(9 1 3 1), 赶上第89位(9 1 3 1 74 1) 等等......你可以清楚地看到它很容易在这里按位置捕获字段,尽管它可以用 OFS
(输出字段分隔符)的东西,但这至少不适用于您显示的示例。